PageRenderTime 55ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/AIT.php

https://github.com/touv/ait
PHP | 2472 lines | 1432 code | 170 blank | 870 comment | 123 complexity | ea28ee339b8c84df6c483ea6c051fde9 MD5 | raw file
Possible License(s): LGPL-2.1

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. // vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 encoding=utf-8 fdm=marker :
  3. // {{{ Licence
  4. // +--------------------------------------------------------------------------+
  5. // | AIT - All is Tag |
  6. // +--------------------------------------------------------------------------+
  7. // | Copyright (C) 2009 Nicolas Thouvenin |
  8. // +--------------------------------------------------------------------------+
  9. // | This library is free software; you can redistribute it and/or |
  10. // | modify it under the terms of the GNU General Public License |
  11. // | as published by the Free Software Foundation; either version 2 |
  12. // | of the License, or (at your option) any later version. |
  13. // | |
  14. // | This program is distributed in the hope that it will be useful, |
  15. // | but WITHOUT ANY WARRANTY; without even the implied warranty of |
  16. // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
  17. // | General Public License for more details. |
  18. // | |
  19. // | You should have received a copy of the GNU General Public License |
  20. // | along with this library; if not, write to the Free Software |
  21. // | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
  22. // +--------------------------------------------------------------------------+
  23. // }}}
  24. /**
  25. * @category AIT
  26. * @package AIT
  27. * @author Nicolas Thouvenin <nthouvenin@gmail.com>
  28. * @copyright 2009 Nicolas Thouvenin
  29. * @license http://opensource.org/licenses/lgpl-license.php LGPL
  30. * @version SVN: $Id$
  31. * @link http://ait.touv.fr/
  32. * */
  33. /**
  34. * Dépendances
  35. */
  36. require_once 'AIT/ItemType.php';
  37. require_once 'AIT/Item.php';
  38. require_once 'AIT/TagType.php';
  39. require_once 'AIT/Tag.php';
  40. /**
  41. * Objet représantant un schéma au sens AIT
  42. *
  43. * @category AIT
  44. * @package AIT
  45. * @author Nicolas Thouvenin <nthouvenin@gmail.com>
  46. * @copyright 2009 Nicolas Thouvenin
  47. * @license http://opensource.org/licenses/lgpl-license.php LGPL
  48. * @link http://ait.touv.fr/
  49. */
  50. class AITSchema {
  51. private $_pointers = array();
  52. // {{{ __construct
  53. /**
  54. * purifie une chaine de carctère représantant un type en une chaine compatible php
  55. *
  56. * @param PDOAIT connexion à la base
  57. * @param string Type d'Item
  58. * @param array tableau de type de tag
  59. */
  60. function __construct(PDOAIT $pdo, $name, array $attributs)
  61. {
  62. $n = $this->_toVarname($name);
  63. $this->_pointers[$n] = new AIT_ItemType($name, $pdo);
  64. foreach($attributs as $attr) {
  65. $a = $this->_toVarname($attr);
  66. $this->_pointers[$a] = $this->_pointers[$n]->getTag($attr);
  67. if (is_null($this->_pointers[$a])) {
  68. $this->_pointers[$a] = $this->_pointers[$n]->addTag($attr);
  69. }
  70. }
  71. }
  72. // }}}
  73. // {{{ _toVarname
  74. /**
  75. * purifie une chaine de carctère représantant un type en une chaine compatible php
  76. *
  77. * @param string $name
  78. *
  79. * @return string
  80. */
  81. private function _toVarname($s)
  82. {
  83. return '_'.md5(trim(strtolower($s)));
  84. }
  85. // }}}
  86. // {{{ __get
  87. /**
  88. * Retroune un objet AIT
  89. *
  90. * @param string $name
  91. *
  92. * @return mixed
  93. */
  94. public function __get($name) {
  95. $n = $this->_toVarname($name);
  96. if (array_key_exists($n, $this->_pointers))
  97. return $this->_pointers[$n];
  98. else
  99. return null;
  100. }
  101. // }}}
  102. }
  103. /**
  104. * Objet de connexion à la base
  105. *
  106. * @category AIT
  107. * @package AIT
  108. * @author Nicolas Thouvenin <nthouvenin@gmail.com>
  109. * @copyright 2009 Nicolas Thouvenin
  110. * @license http://opensource.org/licenses/lgpl-license.php LGPL
  111. * @link http://ait.touv.fr/
  112. */
  113. class PDOAIT extends PDO
  114. {
  115. private $_options = array(
  116. 'dsn' => '',
  117. 'username' => '',
  118. 'password' => '',
  119. 'drvropts' => array(),
  120. 'prefix' => '',
  121. 'opt' => 'opt',
  122. 'tag' => 'tag',
  123. 'tagged' => 'rel',
  124. 'dat' => 'dat',
  125. 'callbacks' => array(),
  126. 'extends' => array(),
  127. );
  128. // {{{ __construct
  129. /**
  130. * Constructeur
  131. *
  132. * @param string $dsn chaine de connexion
  133. * @param string $username user de connexion
  134. * @param string $password mot de passe de connexion
  135. * @param array $driver_options options pour pdo
  136. */
  137. public function __construct($dsn, $username = null, $password = null, $driver_options = null)
  138. {
  139. parent::__construct($dsn, $username, $password, $driver_options);
  140. $this->setOption('dsn', $dsn);
  141. $this->setOption('username', $username);
  142. $this->setOption('password', $password);
  143. $this->setOption('drvropts', $driver_options);
  144. }
  145. // }}}
  146. // {{{ extendsWith
  147. /**
  148. * Ajoute à AIT un module complémentaire
  149. *
  150. * @param AIT_Extended $o
  151. *
  152. * @return PDOAIT
  153. */
  154. public function extendWith(AIT_Extended $o)
  155. {
  156. $o->register($this);
  157. $this->_options['extends'][] = $o;
  158. return $this;
  159. }
  160. // }}}
  161. // {{{ getOption
  162. /**
  163. * renvoit la valeur d'une option
  164. *
  165. * @param string $name name
  166. * @return string
  167. */
  168. public function getOption($n)
  169. {
  170. if (isset($this->_options[$n])) {
  171. return $this->_options[$n];
  172. }
  173. }
  174. // }}}
  175. // {{{ getOptions
  176. /**
  177. * Retourne les options
  178. *
  179. * @param array $a tableau d'option
  180. */
  181. public function getOptions()
  182. {
  183. return $this->_options;
  184. }
  185. // }}}
  186. // {{{ setOption
  187. /**
  188. * Fixe une option
  189. *
  190. * @param string $name nom
  191. * @param string $value valeur
  192. * @return string
  193. */
  194. public function setOption($n, $v)
  195. {
  196. if (isset($this->_options[$n]) && !is_null($v)) {
  197. $func = array($this, 'setOption'.ucfirst($n));
  198. if (is_callable($func)) {
  199. call_user_func($func, $v);
  200. }
  201. else {
  202. $this->_options[$n] = $v;
  203. }
  204. }
  205. }
  206. // }}}
  207. // {{{ setOption
  208. /**
  209. * Fixe l'option "callbacks"
  210. *
  211. * @param string $value valeur
  212. * @return string
  213. */
  214. public function setOptionCallbacks($v)
  215. {
  216. reset($v);
  217. while (list($k, ) = each($v)) {
  218. if (!isset($this->_options['callbacks'][$k])) {
  219. $this->_options['callbacks'][$k] = $v[$k];
  220. }
  221. elseif (!is_array($this->_options['callbacks'][$k])) {
  222. $this->_options['callbacks'][$k] = $v[$k];
  223. }
  224. elseif (is_array($this->_options['callbacks'][$k])) {
  225. $this->_options['callbacks'][$k] = array_merge($this->_options['callbacks'][$k], $v[$k]);
  226. }
  227. }
  228. }
  229. // }}}
  230. // {{{ setOptions
  231. /**
  232. * Fixe les options
  233. *
  234. * @param array $a tableau d'option
  235. */
  236. public function setOptions(array $a)
  237. {
  238. foreach($a as $n => $v) $this->setOption($n, $v);
  239. }
  240. // }}}
  241. // {{{ opt
  242. /**
  243. * Renvoit le nom de la table ait
  244. *
  245. * @return string
  246. */
  247. public function opt()
  248. {
  249. return $this->_options['prefix'].$this->_options['opt'];
  250. }
  251. // }}}
  252. // {{{ tag
  253. /**
  254. * Renvoit le nom de la table tag
  255. *
  256. * @param boolean
  257. * @return string
  258. */
  259. public function tag($crud = false)
  260. {
  261. return $this->_options['prefix'].$this->_options['tag'];
  262. }
  263. // }}}
  264. // {{{ tagged
  265. /**
  266. * Renvoit le nom de la table tagged
  267. *
  268. * @param boolean
  269. * @return string
  270. */
  271. public function tagged($crud = false)
  272. {
  273. return $this->_options['prefix'].$this->_options['tagged'];
  274. }
  275. // }}}
  276. // {{{ dat
  277. /**
  278. * Renvoit le nom de la table dat
  279. *
  280. * @param boolean
  281. * @return string
  282. */
  283. public function dat($crud = false)
  284. {
  285. return $this->_options['prefix'].$this->_options['dat'];
  286. }
  287. // }}}
  288. // {{{ checkup
  289. /**
  290. * Controle la validité de la structure de données
  291. *
  292. * @param boolean $init Lance ou non l'initaliasation automatatique (par défaut true)
  293. *
  294. * @return boolean
  295. */
  296. public function checkup($init = true)
  297. {
  298. try {
  299. $sql = sprintf('
  300. SELECT count(*) n FROM %s WHERE label=\'tag\' or label=\'item\' LIMIT 0,1;
  301. ',
  302. $this->tag());
  303. $stmt = $this->query($sql);
  304. $c = (int)$stmt->fetchColumn(0);
  305. $stmt->closeCursor();
  306. if ($c === 0 and $init) $this->_initData();
  307. elseif ($c === 0 and !$init) return false;
  308. }
  309. catch (PDOException $e) {
  310. if ($init) $this->_initTable();
  311. else return false;
  312. }
  313. return true;
  314. }
  315. // }}}
  316. // {{{ registerSchema
  317. /**
  318. * Enregistre un schema AIT (soit un type d'item associé à des types de tags)
  319. *
  320. * @param string Type d'Item
  321. * @param array tableau de type de tag
  322. *
  323. * @return AITSchema
  324. */
  325. public function registerSchema($name, array $attr)
  326. {
  327. return new AITSchema($this, $name, $attr);
  328. }
  329. // }}}
  330. // {{{ _initTable
  331. /**
  332. * Initialise la structure de données
  333. */
  334. private function _initTable()
  335. {
  336. try {
  337. $driver = strtolower($this->getAttribute(PDO::ATTR_DRIVER_NAME));
  338. switch ($driver) {
  339. case 'mysql':
  340. $this->exec(sprintf("
  341. CREATE TABLE %s (
  342. id INTEGER(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  343. label VARCHAR(200) COLLATE latin1_general_cs NOT NULL,
  344. frequency INTEGER(10) UNSIGNED NOT NULL default '0',
  345. type INTEGER(11) UNSIGNED NOT NULL default '0',
  346. updated timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
  347. created timestamp NOT NULL default '0000-00-00 00:00:00',
  348. score INTEGER(10) NOT NULL default '0',
  349. dat_hash BINARY(20) NULL,
  350. language VARCHAR(5) COLLATE latin1_general_cs NULL,
  351. scheme VARCHAR(10) COLLATE latin1_general_cs NULL,
  352. prefix VARCHAR(50) COLLATE latin1_general_cs NULL,
  353. suffix VARCHAR(50) COLLATE latin1_general_cs NULL,
  354. buffer VARCHAR(200) COLLATE latin1_general_cs NULL,
  355. INDEX (label),
  356. FULLTEXT (buffer),
  357. INDEX (score),
  358. INDEX (type),
  359. INDEX (type,created),
  360. INDEX (type,updated),
  361. INDEX (type,score),
  362. INDEX (type,frequency)
  363. ) ENGINE=MYISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_cs;
  364. ", $this->tag(true)));
  365. $this->exec(sprintf("
  366. CREATE TABLE %s (
  367. tag_id INTEGER(11) UNSIGNED NOT NULL,
  368. item_id INTEGER(11) UNSIGNED NOT NULL,
  369. rank INTEGER(11) NOT NULL default '0',
  370. PRIMARY KEY (tag_id, item_id),
  371. INDEX (tag_id),
  372. INDEX (item_id)
  373. ) ENGINE=MYISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_cs;
  374. ", $this->tagged(true)));
  375. $this->exec(sprintf("
  376. CREATE TABLE %s (
  377. hash BINARY(20) NOT NULL,
  378. content TEXT COLLATE latin1_general_cs NOT NULL,
  379. PRIMARY KEY (hash),
  380. FULLTEXT (content)
  381. ) ENGINE=MYISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_cs;
  382. ", $this->dat(true)));
  383. $this->exec(sprintf("
  384. CREATE TABLE %s (
  385. name VARCHAR(10) COLLATE latin1_general_cs NOT NULL,
  386. value VARCHAR(200) COLLATE latin1_general_cs NOT NULL,
  387. PRIMARY KEY (name)
  388. ) ENGINE=MYISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_cs;
  389. ", $this->opt(true)));
  390. $this->exec(sprintf("
  391. INSERT INTO %s VALUES ('version', '%s');
  392. ", $this->opt(true), AIT::VERSION));
  393. $this->_initData();
  394. break;
  395. default:
  396. throw new Exception($driver.' not supported by AIT.');
  397. }
  398. }
  399. catch (PDOException $e) {
  400. AIT::catchError($e);
  401. }
  402. }
  403. // }}}
  404. // {{{ _initData
  405. /**
  406. * Initialise les données obligatoires
  407. * @param PDO $this Pointeur sur la base de données
  408. */
  409. private function _initData()
  410. {
  411. try {
  412. $this->exec(sprintf(
  413. "INSERT INTO %s (id, label, created) VALUES (%s, 'item', now());",
  414. $this->tag(true),
  415. AIT::ITEM
  416. ));
  417. $this->exec(sprintf(
  418. "INSERT INTO %s (id, label, created) VALUES (%s, 'tag', now());",
  419. $this->tag(true),
  420. AIT::TAG
  421. ));
  422. }
  423. catch (PDOException $e) {
  424. AIT::catchError($e);
  425. }
  426. }
  427. // }}}
  428. }
  429. /**
  430. * Objet Racine
  431. *
  432. * @category AIT
  433. * @package AIT
  434. * @author Nicolas Thouvenin <nthouvenin@gmail.com>
  435. * @copyright 2009 Nicolas Thouvenin
  436. * @license http://opensource.org/licenses/lgpl-license.php LGPL
  437. * @link http://ait.touv.fr/
  438. */
  439. abstract class AITRoot
  440. {
  441. /**
  442. * @var PDOAIT
  443. */
  444. private $_pdo;
  445. /**
  446. * @var array
  447. */
  448. protected $_pdo_opt;
  449. // {{{ getPDO
  450. /**
  451. * Renvoit l'objet PDO utilisé
  452. *
  453. * @return PDO
  454. */
  455. public function getPDO()
  456. {
  457. if (is_null($this->_pdo)) {
  458. $this->_pdo = new PDOAIT(
  459. $this->_pdo_opt['dsn'],
  460. $this->_pdo_opt['username'],
  461. $this->_pdo_opt['password'],
  462. $this->_pdo_opt['drvropts']
  463. );
  464. }
  465. $this->_pdo->setOptions($this->_pdo_opt);
  466. return $this->_pdo;
  467. }
  468. // }}}
  469. // {{{ setPDO
  470. /**
  471. * Fixe l'objet PDO utilisé
  472. *
  473. * @param PDOAIT
  474. */
  475. public function setPDO(PDOAIT $pdo)
  476. {
  477. $this->_pdo = $pdo;
  478. $this->_pdo_opt = $pdo->getOptions();
  479. }
  480. // }}}
  481. // {{{ __sleep
  482. /**
  483. * Avant serialization
  484. *
  485. */
  486. public function __sleep ()
  487. {
  488. $this->_pdo_opt = $this->getPDO()->getOptions();
  489. $vars = array_keys(get_object_vars($this));
  490. unset($vars[array_search('_pdo', $vars)]);
  491. return $vars;
  492. }
  493. // }}}
  494. }
  495. /**
  496. * Classe principale.
  497. * Utilisé de manière statique, elle gére la connection à la base et son initialisation.
  498. * Dans les autres cas elle sert de classe abstraite pour toutes les composantes du système.
  499. *
  500. * @category AIT
  501. * @package AIT
  502. * @author Nicolas Thouvenin <nthouvenin@gmail.com>
  503. * @copyright 2009 Nicolas Thouvenin
  504. * @license http://opensource.org/licenses/lgpl-license.php LGPL
  505. * @link http://ait.touv.fr/
  506. */
  507. class AIT extends AITRoot
  508. {
  509. /**
  510. * @var boolean
  511. */
  512. static $debugging = false;
  513. /**
  514. * @var integer
  515. */
  516. static $time = 0;
  517. /**
  518. * @var integer
  519. */
  520. protected $_id;
  521. /**
  522. * @var string
  523. */
  524. protected $_element;
  525. /**
  526. * @var string
  527. */
  528. protected $_label;
  529. /**
  530. * @var integer
  531. */
  532. protected $_type;
  533. /**
  534. * @var array
  535. */
  536. protected $_methods = array();
  537. /**
  538. * @var array
  539. */
  540. protected $_cols = array(
  541. 'language' => 'string',
  542. 'scheme' => 'string',
  543. 'prefix' => 'string',
  544. 'suffix' => 'string',
  545. 'buffer' => 'string',
  546. 'dat_hash' => 'string',
  547. 'score' => 'integer',
  548. 'frequency' => 'integer',
  549. );
  550. /**
  551. * @var array
  552. */
  553. protected $_data = array();
  554. const VERSION = '2.0.0';
  555. const ORDER_ASC = 2;
  556. const ORDER_DESC = 4;
  557. const ORDER_BY_LABEL = 8;
  558. const ORDER_BY_SCORE = 16;
  559. const ORDER_BY_UPDATED = 32;
  560. const ORDER_BY_CREATED = 64;
  561. const ORDER_BY_FREQUENCY = 128;
  562. const ORDER_BY_RANK = 256;
  563. const INSERT_FIRST = 0;
  564. const ITEM = 1;
  565. const TAG = 2;
  566. // {{{ __construct
  567. /**
  568. * Constructeur
  569. *
  570. * @param PDOAIT $pdo objet de connexion à la base
  571. */
  572. function __construct(PDOAIT $pdo, $element)
  573. {
  574. $this->setPDO($pdo);
  575. $this->_element = $element;
  576. $cb = $this->getPDO()->getOption('callbacks');
  577. if (isset($cb[$element])) $this->setClassCallback($cb[$element]);
  578. }
  579. // }}}
  580. // {{{ catchError
  581. /**
  582. * Attrape toutes les erreurs de l'objet
  583. *
  584. * @param integer $m identifiant du tag
  585. * @param integer $i identifiant du tag
  586. *
  587. * @return boolean
  588. */
  589. public static function catchError(PDOException $e)
  590. {
  591. trigger_error($e->getMessage(), E_USER_ERROR);
  592. }
  593. // }}}
  594. // {{{ connect
  595. /**
  596. * Connection à la base
  597. *
  598. * @param string $dsn chaine de connexion
  599. * @param string $username user de connexion
  600. * @param string $password mot de passe de connexion
  601. * @param array $driver_options options pour pdo
  602. * @param array $ait_options options pour pdo
  603. *
  604. * @return PDO
  605. */
  606. public static function connect($dsn, $username = 'root', $password = '', array $driver_options = array(), array $ait_options = array())
  607. {
  608. try {
  609. $pdo = new PDOAIT($dsn, $username, $password, $driver_options);
  610. $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  611. } catch (PDOException $e) {
  612. AIT::catchError($e);
  613. }
  614. $pdo->setOptions($ait_options);
  615. return $pdo;
  616. }
  617. // }}}
  618. // {{{ setClassCallback
  619. /**
  620. * Fixe des callback de class cad l'ajout de nouvelle méthode
  621. *
  622. * @access public
  623. */
  624. function setClassCallback(array $a)
  625. {
  626. foreach($a as $n => $c) {
  627. if (is_callable($c, true)) {
  628. $this->_methods[$n] = $c;
  629. }
  630. else {
  631. trigger_error($n.' passed to '.__METHOD__.' must be a valid callback', E_USER_ERROR);
  632. }
  633. }
  634. }
  635. // }}}
  636. // {{{ isClassCallback
  637. /**
  638. * Test si la callback est définie
  639. *
  640. * @access public
  641. */
  642. function isClassCallback($c)
  643. {
  644. if (isset($this->_methods[$c]))
  645. return true;
  646. else
  647. return false;
  648. }
  649. // }}}
  650. // {{{ callClassCallback
  651. /**
  652. * Lance une callback
  653. *
  654. * @param string name
  655. * @access public
  656. */
  657. function callClassCallback()
  658. {
  659. $c = func_get_arg(0);
  660. $r = func_get_args();
  661. array_shift($r);
  662. if ($this->isClassCallback($c)) {
  663. return call_user_func_array($this->_methods[$c], $r);
  664. }
  665. else
  666. return false;
  667. }
  668. // }}}
  669. // {{{ ren
  670. /**
  671. * Renomme l'élement courrant
  672. *
  673. * @param string $l nouveau label
  674. */
  675. function ren($l)
  676. {
  677. if ($l !== $this->_label) {
  678. $this->callClassCallback('renHook', $l, $this);
  679. $this->_label = $l;
  680. $this->_set('label', $this->_label);
  681. }
  682. }
  683. // }}}
  684. // {{{ exists
  685. /**
  686. * Verifie l'existence de l'élement courrant
  687. */
  688. function exists()
  689. {
  690. try {
  691. $sql = sprintf('
  692. SELECT count(*) FROM %s WHERE id=? LIMIT 0,1
  693. ',
  694. $this->getPDO()->tag()
  695. );
  696. $stmt = $this->getPDO()->prepare($sql);
  697. $stmt->bindParam(1, $this->_id, PDO::PARAM_INT);
  698. $stmt->execute();
  699. settype($this->_id, 'integer');
  700. $c = (int)$stmt->fetchColumn(0);
  701. $stmt->closeCursor();
  702. if ($c > 0) return true;
  703. else return false;
  704. }
  705. catch (PDOException $e) {
  706. self::catchError($e);
  707. }
  708. }
  709. // }}}
  710. // {{{ _checkTag
  711. /**
  712. * Vérifie l'existance et le type d'un tag
  713. * retourne false en cas de problème
  714. *
  715. * @param integer $i identifiant du tag
  716. * @param integer $t identifiant de son type
  717. *
  718. * @return boolean
  719. */
  720. protected function _checkTag($i, $t)
  721. {
  722. try {
  723. $sql = sprintf('
  724. SELECT count(*) n FROM %s WHERE id=? AND type=? LIMIT 0,1
  725. ',
  726. $this->getPDO()->tag()
  727. );
  728. $stmt = $this->getPDO()->prepare($sql);
  729. $stmt->bindParam(1, $i, PDO::PARAM_INT);
  730. $stmt->bindParam(2, $t, PDO::PARAM_INT);
  731. $stmt->execute();
  732. settype($i, 'integer');
  733. settype($t, 'integer');
  734. $c = (int)$stmt->fetchColumn(0);
  735. $stmt->closeCursor();
  736. if ($c > 0) return true;
  737. else return false;
  738. }
  739. catch (PDOException $e) {
  740. self::catchError($e);
  741. }
  742. }
  743. // }}}
  744. // {{{ _checkType
  745. /**
  746. * Vérifie l'existance d'un type d'un tag
  747. *
  748. * @param integer $t identifiant de son type
  749. *
  750. * @return boolean
  751. */
  752. protected function _checkType($t)
  753. {
  754. try {
  755. $sql = sprintf('
  756. SELECT count(*) FROM %s WHERE id=? LIMIT 0,1
  757. ',
  758. $this->getPDO()->tag()
  759. );
  760. $stmt = $this->getPDO()->prepare($sql);
  761. $stmt->bindParam(1, $t, PDO::PARAM_INT);
  762. $stmt->execute();
  763. $c = (int)$stmt->fetchColumn(0);
  764. $stmt->closeCursor();
  765. if ($c > 0) return true;
  766. else return false;
  767. }
  768. catch (PDOException $e) {
  769. self::catchError($e);
  770. }
  771. }
  772. // }}}
  773. // {{{ _checkTagged
  774. /**
  775. * Vérifie l'existance de l'association d'un tag et d'un item
  776. *
  777. * @param integer $m identifiant du tag
  778. * @param integer $i identifiant de l'item
  779. *
  780. * @return boolean
  781. */
  782. protected function _checkTagged($m, $i)
  783. {
  784. try {
  785. $sql = sprintf('
  786. SELECT count(*) n FROM %s WHERE tag_id=? and item_id=? LIMIT 0,1
  787. ',
  788. $this->getPDO()->tagged()
  789. );
  790. $stmt = $this->getPDO()->prepare($sql);
  791. $stmt->bindParam(1, $m, PDO::PARAM_INT);
  792. $stmt->bindParam(2, $i, PDO::PARAM_INT);
  793. $stmt->execute();
  794. settype($m, 'integer');
  795. settype($i, 'integer');
  796. $c = (int)$stmt->fetchColumn(0);
  797. $stmt->closeCursor();
  798. if ($c > 0) return true;
  799. else return false;
  800. }
  801. catch (PDOException $e) {
  802. self::catchError($e);
  803. }
  804. }
  805. // }}}
  806. // {{{ _increaseFrequency
  807. /**
  808. * Incremente la frequence d'une ligne dans TAG
  809. *
  810. * @param string $t id
  811. */
  812. protected function _increaseFrequency($i)
  813. {
  814. try {
  815. $sql = sprintf('
  816. SELECT frequency FROM %s WHERE id = ? LIMIT 0,1
  817. ',
  818. $this->getPDO()->tag()
  819. );
  820. self::timer();
  821. $stmt = $this->getPDO()->prepare($sql);
  822. $stmt->bindParam(1, $i, PDO::PARAM_INT);
  823. $stmt->execute();
  824. settype($i, 'integer');
  825. $f = (int) $stmt->fetchColumn(0);
  826. $stmt->closeCursor();
  827. self::debug(self::timer(true), $sql, $i);
  828. ++$f;
  829. if ($f <= 0) $f = 1; // Control IMPORTANT
  830. $sql = sprintf('
  831. UPDATE %s SET frequency = ? WHERE id = ?
  832. ',
  833. $this->getPDO()->tag(true)
  834. );
  835. self::timer();
  836. $stmt = $this->getPDO()->prepare($sql);
  837. $stmt->bindParam(1, $f, PDO::PARAM_INT);
  838. $stmt->bindParam(2, $i, PDO::PARAM_INT);
  839. $stmt->execute();
  840. settype($f, 'integer');
  841. settype($i, 'integer');
  842. $stmt->closeCursor();
  843. self::debug(self::timer(true), $sql, $f, $i);
  844. }
  845. catch (PDOException $e) {
  846. self::catchError($e);
  847. }
  848. }
  849. // }}}
  850. // {{{ _decreaseFrequency
  851. /**
  852. * Incremente la frequence d'une ligne dans TAG
  853. *
  854. * @param string $t id
  855. */
  856. protected function _decreaseFrequency($i)
  857. {
  858. try {
  859. $sql = sprintf('
  860. SELECT frequency FROM %s WHERE id = ? LIMIT 0,1
  861. ',
  862. $this->getPDO()->tag()
  863. );
  864. self::timer();
  865. $stmt = $this->getPDO()->prepare($sql);
  866. $stmt->bindParam(1, $i, PDO::PARAM_INT);
  867. $stmt->execute();
  868. settype($i, 'integer');
  869. $f = (int) $stmt->fetchColumn(0);
  870. $stmt->closeCursor();
  871. self::debug(self::timer(true), $sql, $i);
  872. --$f;
  873. if ($f <= 0) $f = 0; // Control IMPORTANT
  874. $sql = sprintf('
  875. UPDATE %s SET frequency = ? WHERE id = ?
  876. ',
  877. $this->getPDO()->tag(true)
  878. );
  879. self::timer();
  880. $stmt = $this->getPDO()->prepare($sql);
  881. $stmt->bindParam(1, $f, PDO::PARAM_INT);
  882. $stmt->bindParam(2, $i, PDO::PARAM_INT);
  883. $stmt->execute();
  884. settype($f, 'integer');
  885. settype($i, 'integer');
  886. $stmt->closeCursor();
  887. self::debug(self::timer(true), $sql, $f, $i);
  888. }
  889. catch (PDOException $e) {
  890. self::catchError($e);
  891. }
  892. }
  893. // }}}
  894. // {{{ _addTagged
  895. /**
  896. * Ajout d'une ligne dans la table tagged
  897. *
  898. * @param string $t tag id
  899. * @param string $i item id
  900. * @param in $p position
  901. */
  902. protected function _addTagged($t, $i, $p = null)
  903. {
  904. try {
  905. if (is_null($p) or $p === 0) {
  906. $sql = sprintf('
  907. INSERT INTO %1$s (tag_id, item_id, rank) SELECT ?, ?, %2$s FROM %1$s WHERE item_id = ? LIMIT 0,1
  908. ',
  909. $this->getPDO()->tagged(true),
  910. ($p === 0 ? 'min(rank) - 1' : 'max(rank) + 1')
  911. );
  912. self::timer();
  913. $stmt = $this->getPDO()->prepare($sql);
  914. $stmt->bindParam(1, $t, PDO::PARAM_INT);
  915. $stmt->bindParam(2, $i, PDO::PARAM_INT);
  916. $stmt->bindParam(3, $i, PDO::PARAM_INT);
  917. $stmt->execute();
  918. settype($t, 'integer');
  919. settype($i, 'integer');
  920. $stmt->closeCursor();
  921. self::debug(self::timer(true), $sql, $t, $i, $i);
  922. }
  923. else {
  924. $sql = sprintf('
  925. SELECT rank
  926. FROM %s
  927. WHERE tag_id = ? and item_id = ?
  928. ',
  929. $this->getPDO()->tagged(true)
  930. );
  931. self::timer();
  932. $stmt = $this->getPDO()->prepare($sql);
  933. $stmt->bindParam(1, $p, PDO::PARAM_INT);
  934. $stmt->bindParam(2, $i, PDO::PARAM_INT);
  935. $stmt->execute();
  936. $rank = (int) $stmt->fetchColumn(0);
  937. settype($p, 'integer');
  938. settype($i, 'integer');
  939. $stmt->closeCursor();
  940. self::debug(self::timer(true), $sql, $p, $i);
  941. $sql = '
  942. SET @rank = ?;
  943. ';
  944. self::timer();
  945. $stmt = $this->getPDO()->prepare($sql);
  946. $stmt->bindParam(1, $rank, PDO::PARAM_INT);
  947. $stmt->execute();
  948. settype($rank, 'integer');
  949. settype($i, 'integer');
  950. $stmt->closeCursor();
  951. self::debug(self::timer(true), $sql, $rank);
  952. $sql = sprintf('
  953. UPDATE %s SET rank = (SELECT @rank := @rank + 1) WHERE item_id = ? ORDER BY rank;
  954. ',
  955. $this->getPDO()->tagged(true)
  956. );
  957. self::timer();
  958. $stmt = $this->getPDO()->prepare($sql);
  959. $stmt->bindParam(1, $i, PDO::PARAM_INT);
  960. $stmt->execute();
  961. settype($rank, 'integer');
  962. settype($i, 'integer');
  963. $stmt->closeCursor();
  964. self::debug(self::timer(true), $sql, $i);
  965. ++$rank;
  966. $sql = sprintf('
  967. INSERT INTO %s (tag_id, item_id, rank) VALUES (?, ?, ?);
  968. ',
  969. $this->getPDO()->tagged(true)
  970. );
  971. self::timer();
  972. $stmt = $this->getPDO()->prepare($sql);
  973. $stmt->bindParam(1, $t, PDO::PARAM_INT);
  974. $stmt->bindParam(2, $i, PDO::PARAM_INT);
  975. $stmt->bindParam(3, $rank, PDO::PARAM_INT);
  976. $stmt->execute();
  977. settype($t, 'integer');
  978. settype($i, 'integer');
  979. settype($rank, 'integer');
  980. $stmt->closeCursor();
  981. self::debug(self::timer(true), $sql, $t, $i, $rank);
  982. }
  983. }
  984. catch (PDOException $e) {
  985. self::catchError($e);
  986. }
  987. }
  988. // }}}
  989. // {{{ _rmTagged
  990. /**
  991. * Supprime une ligne dans la table tagged
  992. *
  993. * @param string $t tag id
  994. * @param string $i item id
  995. */
  996. protected function _rmTagged($t, $i)
  997. {
  998. try {
  999. if (is_null($t) and !is_null($i)) {
  1000. $field = 'item_id';
  1001. $value = $i;
  1002. }
  1003. elseif (!is_null($t) and is_null($i)) {
  1004. $field = 'tag_id';
  1005. $value = $t;
  1006. }
  1007. else
  1008. throw new Exception('Bad Arguments');
  1009. $sql = sprintf('
  1010. DELETE FROM %s WHERE %s=?
  1011. ',
  1012. $this->getPDO()->tagged(true),
  1013. $field
  1014. );
  1015. self::timer();
  1016. $stmt = $this->getPDO()->prepare($sql);
  1017. $stmt->bindParam(1, $value, PDO::PARAM_INT);
  1018. $stmt->execute();
  1019. $stmt->closeCursor();
  1020. self::debug(self::timer(true), $sql, $this->_id);
  1021. }
  1022. catch (PDOException $e) {
  1023. self::catchError($e);
  1024. }
  1025. }
  1026. // }}}
  1027. // {{{ _rmTag
  1028. /**
  1029. * Suppression d'une ligne dans tag
  1030. *
  1031. */
  1032. protected function _rmTag()
  1033. {
  1034. $dat_hash = $this->_get('dat_hash', true);
  1035. try {
  1036. $sql = sprintf('
  1037. DELETE FROM %s WHERE id=?
  1038. ',
  1039. $this->getPDO()->tag(true)
  1040. );
  1041. self::timer();
  1042. $stmt = $this->getPDO()->prepare($sql);
  1043. $stmt->bindParam(1, $this->_id, PDO::PARAM_INT);
  1044. $stmt->execute();
  1045. settype($this->_id, 'integer');
  1046. $stmt->closeCursor();
  1047. self::debug(self::timer(true), $sql, $this->_id);
  1048. $this->_id = null;
  1049. $sql = sprintf('
  1050. DELETE FROM %2$s
  1051. USING %2$s
  1052. LEFT JOIN %1$s tag ON %2$s.hash=tag.dat_hash
  1053. WHERE hash=? AND tag.id is NULL
  1054. ',
  1055. $this->getPDO()->tag(true),
  1056. $this->getPDO()->dat(true)
  1057. );
  1058. self::timer();
  1059. $stmt = $this->getPDO()->prepare($sql);
  1060. $stmt->bindParam(1, $dat_hash, PDO::PARAM_STR);
  1061. $stmt->execute();
  1062. $stmt->closeCursor();
  1063. self::debug(self::timer(true), $sql, $dat_hash);
  1064. }
  1065. catch (PDOException $e) {
  1066. self::catchError($e);
  1067. }
  1068. }
  1069. // }}}
  1070. // {{{ _addTag
  1071. /**
  1072. * Ajout d'une ligne dans la table tag
  1073. *
  1074. * @param string $l label
  1075. * @param string $t type
  1076. * @param array $r champ associé
  1077. *
  1078. * @return integer
  1079. */
  1080. protected function _addTag($l, $t = null, $r = false)
  1081. {
  1082. try {
  1083. $sql = sprintf('
  1084. SELECT id FROM %s WHERE label=? and type=? LIMIT 0,1
  1085. ',
  1086. $this->getPDO()->tag()
  1087. );
  1088. $stmt = $this->getPDO()->prepare($sql);
  1089. $stmt->bindParam(1, $l, PDO::PARAM_STR);
  1090. $stmt->bindParam(2, $t, PDO::PARAM_INT);
  1091. $stmt->execute();
  1092. settype($t, 'integer');
  1093. $id = $stmt->fetchColumn();
  1094. $stmt->closeCursor();
  1095. if ($id !== false) return (int) $id;
  1096. if (isset($r['content'])) {
  1097. $r['dat_hash'] = sha1($r['content'], true);
  1098. self::timer();
  1099. $sql = sprintf('
  1100. INSERT IGNORE INTO %s (hash, content) VALUES (?, ?);
  1101. ',
  1102. $this->getPDO()->dat(true)
  1103. );
  1104. $stmt = $this->getPDO()->prepare($sql);
  1105. $stmt->bindParam(1, $r['dat_hash'], PDO::PARAM_STR);
  1106. $stmt->bindParam(2, $r['content'], PDO::PARAM_STR);
  1107. $ret = $stmt->execute();
  1108. $stmt->closeCursor();
  1109. self::debug(self::timer(true), $sql, $r['dat_hash'], $r['content']);
  1110. }
  1111. $sqlA = $sqlB = '';
  1112. $fields = array();
  1113. foreach($this->_cols as $name => $typage) {
  1114. if (isset($r[$name])) {
  1115. settype($r[$name], $typage);
  1116. $fields[] = $this->_data[$name] = $r[$name];
  1117. $sqlA .= ','.$name;
  1118. $sqlB .= ',?';
  1119. }
  1120. }
  1121. self::timer();
  1122. if (is_null($t)) {
  1123. $sql = sprintf('
  1124. INSERT INTO %s (label, updated, created %s) VALUES (?, now(), now() %s);
  1125. ',
  1126. $this->getPDO()->tag(true),
  1127. $sqlA,
  1128. $sqlB
  1129. );
  1130. $stmt = $this->getPDO()->prepare($sql);
  1131. $stmt->bindParam(1, $l, PDO::PARAM_STR);
  1132. $n = 2;
  1133. }
  1134. else {
  1135. $sql = sprintf('
  1136. INSERT INTO %s (label, type, updated, created %s) VALUES (?, ?, now(), now() %s);
  1137. ',
  1138. $this->getPDO()->tag(true),
  1139. $sqlA,
  1140. $sqlB
  1141. );
  1142. $stmt = $this->getPDO()->prepare($sql);
  1143. $stmt->bindParam(1, $l, PDO::PARAM_STR);
  1144. $stmt->bindParam(2, $t, PDO::PARAM_INT);
  1145. $n = 3;
  1146. }
  1147. foreach($fields as $k => $field) {
  1148. $typage = gettype($field);
  1149. if ($typage === 'integer')
  1150. $stmt->bindParam($k + $n, $field, PDO::PARAM_INT);
  1151. elseif ($typage === 'string')
  1152. $stmt->bindParam($k + $n, $field, PDO::PARAM_STR);
  1153. }
  1154. $ret = $stmt->execute();
  1155. $stmt->closeCursor();
  1156. self::debug(self::timer(true), $sql, $l, $t, $r);
  1157. $id = (int) $this->getPDO()->lastInsertId();
  1158. }
  1159. catch (PDOException $e) {
  1160. self::catchError($e);
  1161. }
  1162. return $id;
  1163. }
  1164. // }}}
  1165. // {{{ _getTagBySystemID
  1166. /**
  1167. * Retroune une ligne dans la table tag à partir de l'identifiant physique
  1168. *
  1169. * @param integer $i
  1170. *
  1171. * @return array
  1172. */
  1173. protected function _getTagBySystemID($i)
  1174. {
  1175. $sql = sprintf('
  1176. SELECT id, label, prefix, suffix, buffer, scheme, dat_hash, language, score, frequency, type, content
  1177. FROM %s tag
  1178. LEFT JOIN %s dat ON tag.dat_hash=dat.hash
  1179. WHERE id = ?
  1180. LIMIT 0,1
  1181. ',
  1182. $this->getPDO()->tag(),
  1183. $this->getPDO()->dat()
  1184. );
  1185. self::timer();
  1186. if (($r = $this->callClassCallback(
  1187. 'getTagBySystemIDCache',
  1188. $cid = self::str2cid($sql, $i)
  1189. )) !== false) return $r;
  1190. try {
  1191. $stmt = $this->getPDO()->prepare($sql);
  1192. $stmt->bindParam(1, $i, PDO::PARAM_INT);
  1193. $stmt->execute();
  1194. $row = $stmt->fetch(PDO::FETCH_ASSOC);
  1195. $stmt->closeCursor();
  1196. }
  1197. catch (PDOException $e) {
  1198. self::catchError($e);
  1199. }
  1200. self::debug(self::timer(true), $sql, $i);
  1201. if (is_array($row)) {
  1202. settype($row['type'], 'integer');
  1203. settype($row['id'], 'integer');
  1204. }
  1205. if (isset($cid))
  1206. $this->callClassCallback('getTagBySystemIDCache', $cid, $row);
  1207. return $row;
  1208. }
  1209. // }}}
  1210. // {{{ _set
  1211. /**
  1212. * Méthode permettant de changer la valeur d'une colonne
  1213. *
  1214. * @param string $name nom de la colonne
  1215. * @param mixed $value valeur de la colonne
  1216. */
  1217. protected function _set($n, $v)
  1218. {
  1219. $this->callClassCallback('setHook', $n, $v, $this);
  1220. $this->_data[$n] = $v;
  1221. if ($n === 'content') {
  1222. $dat_hash = sha1($r['content'], true);
  1223. $this->_set('dat_hash', $dat_hash);
  1224. self::timer();
  1225. $sql = sprintf('
  1226. INSERT IGNORE INTO %s (hash, content) VALUES (?, ?);
  1227. ',
  1228. $this->getPDO()->dat(true)
  1229. );
  1230. $stmt = $this->getPDO()->prepare($sql);
  1231. $stmt->bindParam(1, $dat_hash, PDO::PARAM_STR);
  1232. $stmt->bindParam(2, $v, PDO::PARAM_STR);
  1233. $ret = $stmt->execute();
  1234. $stmt->closeCursor();
  1235. self::debug(self::timer(true), $sql, $dat_hash, $v);
  1236. }
  1237. try {
  1238. self::timer();
  1239. $sql = sprintf('
  1240. UPDATE %s set %s=? WHERE id=?
  1241. ',
  1242. $this->getPDO()->tag(true), $n
  1243. );
  1244. $stmt = $this->getPDO()->prepare($sql);
  1245. $typ = gettype($v);
  1246. if ($typ === 'string')
  1247. $stmt->bindParam(1, $v, PDO::PARAM_STR);
  1248. elseif ($typ === 'integer')
  1249. $stmt->bindParam(1, $v, PDO::PARAM_INT);
  1250. else
  1251. throw new Exception('type not supported (`'.$typ.'`)');
  1252. $stmt->bindParam(2, $this->_id, PDO::PARAM_INT);
  1253. $stmt->execute();
  1254. settype($this->_id, 'integer');
  1255. $stmt->closeCursor();
  1256. self::debug(self::timer(true), $sql, $v, $this->_id);
  1257. }
  1258. catch (PDOException $e) {
  1259. self::catchError($e);
  1260. }
  1261. }
  1262. // }}}
  1263. // {{{ _fill
  1264. /**
  1265. * Méthode permettant de charger les propritétes de l'objet
  1266. * à partir d'un tableau de données
  1267. *
  1268. * @param array $a
  1269. */
  1270. protected function _fill($a)
  1271. {
  1272. if (is_array($a)) {
  1273. foreach($this->_cols as $n => $t) {
  1274. if (isset($a[$n])) {
  1275. $this->_data[$n] = $a[$n];
  1276. settype($this->_data[$n], $t);
  1277. }
  1278. }
  1279. if (isset($a['content'])) {
  1280. $this->_data['content'] = $a['content'];
  1281. }
  1282. }
  1283. }
  1284. // }}}
  1285. //
  1286. // {{{ filter
  1287. /**
  1288. * Création de filtre sql sur les colonnes complétaires
  1289. *
  1290. * @param array $a
  1291. * @param strinf $c
  1292. */
  1293. protected function filter($a, $c = 'tag')
  1294. {
  1295. $sql = '';
  1296. if (is_array($a))
  1297. foreach($this->_cols as $n => $t)
  1298. if (isset($a[$n]))
  1299. $sql = ' AND '.$c.'.'.$n.'='.$this->getPDO()->quote($a[$n], $t === 'integer' ? PDO::PARAM_INT : PDO::PARAM_STR);
  1300. return $sql;
  1301. }
  1302. // }}}
  1303. // {{{ _get
  1304. /**
  1305. * Méthode permettant d'accéder à la valeur d'une colonne
  1306. *
  1307. * @param string $n nom de la colonne
  1308. * @param boolean $reload récupére la valeur en base et non celle du cache de l'objet
  1309. *
  1310. * @return mixed
  1311. */
  1312. protected function _get($n, $reload = false)
  1313. {
  1314. if ($reload === true && isset($this->_data[$n])) unset($this->_data[$n]);
  1315. if (!isset($this->_data[$n])) {
  1316. try {
  1317. self::timer();
  1318. $sql = sprintf('
  1319. SELECT id, label, prefix, suffix, buffer, scheme, dat_hash, language, score, frequency, type, content
  1320. FROM %s tag
  1321. LEFT JOIN %s dat ON tag.dat_hash=dat.hash
  1322. WHERE id = ?
  1323. LIMIT 0,1
  1324. ',
  1325. $this->getPDO()->tag(),
  1326. $this->getPDO()->dat()
  1327. );
  1328. $stmt = $this->getPDO()->prepare($sql);
  1329. $stmt->bindParam(1, $this->_id, PDO::PARAM_INT);
  1330. $stmt->execute();
  1331. settype($this->_id, 'integer');
  1332. $a = $stmt->fetch(PDO::FETCH_ASSOC);
  1333. $this->_fill($a);
  1334. $stmt->closeCursor();
  1335. self::debug(self::timer(true), $sql, $this->_id);
  1336. }
  1337. catch (PDOException $e) {
  1338. self::catchError($e);
  1339. }
  1340. }
  1341. return isset($this->_data[$n]) ? $this->_data[$n] : null;
  1342. }
  1343. // }}}
  1344. // {{{ getSystemID
  1345. /**
  1346. * getSystemID
  1347. *
  1348. * @return integer
  1349. */
  1350. public function getSystemID()
  1351. {
  1352. return $this->_id;
  1353. }
  1354. // }}}
  1355. // {{{ get
  1356. /**
  1357. * Getter
  1358. *
  1359. * @param string $name nom de l'attribut
  1360. *
  1361. * @return mixed
  1362. */
  1363. public function get($name = 'label')
  1364. {
  1365. $attr = array(
  1366. 'internal_id' => 'id',
  1367. 'type' => 'type',
  1368. 'label' => 'label',
  1369. 'value' => 'label',
  1370. );
  1371. if (isset($attr[$name])) {
  1372. $name = '_'.$attr[$name];
  1373. $value = $this->$name;
  1374. }
  1375. if (isset($this->_cols[$name]) or $name === 'content') {
  1376. $value = $this->_get($name);
  1377. }
  1378. if ($this->isClassCallback('getHook')) {
  1379. $value = $this->callClassCallback('getHook', $name, $value, $this);
  1380. }
  1381. return $value;
  1382. }
  1383. // }}}
  1384. // {{{ set
  1385. /**
  1386. * Setter
  1387. *
  1388. * @param string $value
  1389. * @param string $name nom de l'attribut
  1390. *
  1391. * @return mixed
  1392. */
  1393. public function set($value, $name = 'label')
  1394. {
  1395. if ($name === 'label') {
  1396. return $this->ren($value);
  1397. }
  1398. elseif (isset($this->_cols[$name])) {
  1399. return $this->_set($name, $value);
  1400. }
  1401. }
  1402. // }}}
  1403. // {{{ getTimestamps
  1404. /**
  1405. * getTimestamps
  1406. *
  1407. * @return ArrayObject
  1408. */
  1409. public function getTimestamps()
  1410. {
  1411. try {
  1412. $sql = sprintf('
  1413. SELECT UNIX_TIMESTAMP(updated), UNIX_TIMESTAMP(created) FROM %s WHERE id=? LIMIT 0,1
  1414. ',
  1415. $this->getPDO()->tag()
  1416. );
  1417. $stmt = $this->getPDO()->prepare($sql);
  1418. $stmt->bindParam(1, $this->_id, PDO::PARAM_INT);
  1419. $stmt->execute();
  1420. settype($this->_id, 'integer');
  1421. $ret = $stmt->fetch();
  1422. $stmt->closeCursor();
  1423. return new ArrayObject(
  1424. array(
  1425. 'updated' => (int) $ret[0],
  1426. 'created' => (int) $ret[1],
  1427. ), ArrayObject::ARRAY_AS_PROPS
  1428. );
  1429. }
  1430. catch (PDOException $e) {
  1431. self::catchError($e);
  1432. }
  1433. }
  1434. // }}}
  1435. // {{{ getScore
  1436. /**
  1437. * Revoit le score de l'élement
  1438. *
  1439. * @return integer
  1440. */
  1441. public function getScore()
  1442. {
  1443. return (int) $this->_get('score');
  1444. }
  1445. // }}}
  1446. // {{{ setScore
  1447. /**
  1448. * Revoit le score de l'élement
  1449. *
  1450. * @param integer $i
  1451. */
  1452. public function setScore($i)
  1453. {
  1454. if (!is_int($i))
  1455. trigger_error('Argument 1 passed to '.__METHOD__.' must be a integer, '.gettype($i).' given', E_USER_ERROR);
  1456. $this->_set('score', $i);
  1457. }
  1458. // }}}
  1459. // {{{ setScore
  1460. /**
  1461. * Renvoit la frequence de l'élement
  1462. *
  1463. * @param integer $i
  1464. */
  1465. public function setFrequency($i)
  1466. {
  1467. if (!is_int($i))
  1468. trigger_error('Argument 1 passed to '.__METHOD__.' must be a integer, '.gettype($i).' given', E_USER_ERROR);
  1469. $this->_set('frequency', $i);
  1470. }
  1471. // }}}
  1472. // {{{ search
  1473. /**
  1474. * Recherche un objet quelque soit sont type
  1475. *
  1476. * @param string $query requete (le format dépend de la search_callback) sans callback c'est du SQL
  1477. * @param integer $offset décalage à parir du premier enregistrement
  1478. * @param integer $lines nombre de lignes à retourner
  1479. * @param integer $ordering flag permettant le tri
  1480. *
  1481. * @return AITResult
  1482. */
  1483. public function search($query, $offset = null, $lines = null, $ordering = null)
  1484. {
  1485. if (!is_null($offset) && !is_int($offset))
  1486. trigger_error('Argument 3 passed to '.__METHOD__.' must be a integer, '.gettype($offset).' given', E_USER_ERROR);
  1487. if (!is_null($lines) && !is_int($lines))
  1488. trigger_error('Argument 4 passed to '.__METHOD__.' must be a integer, '.gettype($lines).' given', E_USER_ERROR);
  1489. if (!is_null($ordering) && !is_int($ordering))
  1490. trigger_error('Argument 5 passed to '.__METHOD__.' must be a integer, '.gettype($ordering).' given', E_USER_ERROR);
  1491. if ($this->isClassCallback('searchHook'))
  1492. $query = $this->callClassCallback('searchHook', $query, $this);
  1493. if ($query !== '' and $query !== false) $query = 'AND '.$query;
  1494. $sql1 = 'SELECT tag.id id, tag.label label, tag.type type, tag.prefix prefix, tag.suffix suffix, tag.buffer buffer, tag.scheme scheme, tag.dat_hash dat_hash, tag.language language, tag.score score, tag.frequency frequency, b.type crtl';
  1495. $sql2 = sprintf('
  1496. FROM %1$s tag
  1497. LEFT JOIN %1$s b ON tag.type=b.id
  1498. WHERE tag.type != 0 %2$s
  1499. ',
  1500. $this->getPDO()->tag(),
  1501. $query
  1502. );
  1503. $sql = $sql1.$sql2;
  1504. self::sqler($sql, $offset, $lines, $ordering);
  1505. self::timer();
  1506. $stmt = $this->getPDO()->prepare($sql);
  1507. $stmt->execute();
  1508. $ret = array();
  1509. while (($row = $stmt->fetch(PDO::FETCH_ASSOC))) {
  1510. if (is_null($row['id'])) continue;
  1511. $ret[] = self::factory($this->getPDO(), $row);
  1512. }
  1513. $stmt->closeCursor();
  1514. self::debug(self::timer(true), $sql, $this->_id, $this->_id);
  1515. $sql = 'SELECT COUNT(*) '.$sql2;
  1516. $r = new AITResult($ret);
  1517. $r->setQueryForTotal($sql, array($this->_id => PDO::PARAM_INT,), $this->getPDO());
  1518. return $r;
  1519. }
  1520. // }}}
  1521. // {{{ factory
  1522. /**
  1523. * Créer un objet à partir d'un tableau de donnée
  1524. *
  1525. * @param PDOAIT $pdo pointeur sur la base de données
  1526. * @param array $row
  1527. *
  1528. * @return mixed
  1529. */
  1530. public static function factory(PDOAIT $pdo, $row)
  1531. {
  1532. if (!is_array($row))
  1533. trigger_error('Argument 2 passed to '.__METHOD__.' must be a array, '.gettype($row).' given', E_USER_ERROR);
  1534. if (!isset($row['type']) or !isset($row['id']) or !isset($row['crtl']) or !isset($row['label']))
  1535. trigger_error('Argument 2 passed to '.__METHOD__.' has one or more keys missing (id, label, type, crtl)', E_USER_ERROR);
  1536. settype($row['type'], 'integer');
  1537. settype($row['id'], 'integer');
  1538. settype($row['crtl'], 'integer');
  1539. $o = null;
  1540. if ($row['type'] === self::ITEM) {
  1541. $o = new AIT_ItemType($row['label'], $pdo, $row['id'], $row);
  1542. }
  1543. elseif ($row['type'] === self::TAG) {
  1544. $o = new AIT_TagType($row['label'], null, $pdo, $row['id'], $row);
  1545. }
  1546. elseif ($row['crtl'] === self::ITEM) {
  1547. $o = new AIT_Item($row['label'], $row['type'], $pdo, $row['id'], $row);
  1548. }
  1549. elseif ($row['crtl'] === self::TAG) {
  1550. $o = new AIT_Tag($row['label'], $row['type'], null, $pdo, $row['id'], $row);
  1551. }
  1552. return $o;
  1553. }
  1554. // }}}
  1555. // {{{ getBySystemID
  1556. /**
  1557. * Récupère…

Large files files are truncated, but you can click here to view the full file