PageRenderTime 56ms CodeModel.GetById 28ms RepoModel.GetById 1ms app.codeStats 0ms

/AIT/ItemType.php

https://github.com/touv/ait
PHP | 894 lines | 549 code | 99 blank | 246 comment | 116 complexity | ab96f2ed35bdc3b88239f2449616a1d3 MD5 | raw file
Possible License(s): LGPL-2.1
  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.php';
  37. require_once 'AIT/Item.php';
  38. require_once 'AIT/TagType.php';
  39. /**
  40. * Représente un TYPE d'ITEM
  41. *
  42. * @category AIT
  43. * @package AIT
  44. * @author Nicolas Thouvenin <nthouvenin@gmail.com>
  45. * @copyright 2009 Nicolas Thouvenin
  46. * @license http://opensource.org/licenses/lgpl-license.php LGPL
  47. * @link http://ait.touv.fr/
  48. */
  49. class AIT_ItemType extends AIT
  50. {
  51. private $TagTypes = array();
  52. // {{{ __construct
  53. /**
  54. * Constructeur
  55. *
  56. * @param string $label nom du tupe d'item
  57. * @param PDOAIT $pdo objet de connexion à la base
  58. * @param integer $id Identifiant système de l'élement (si déjà connu).
  59. * @param array $row Propriétés de l'élément (si déja connu)
  60. */
  61. function __construct($l, PDOAIT $pdo, $id = false, $row = false)
  62. {
  63. parent::__construct($pdo, 'ItemType');
  64. if (!is_string($l) and !is_null($l) and $id !== false)
  65. trigger_error('Argument 1 passed to '.__METHOD__.' must be a string, '.gettype($l).' given', E_USER_ERROR);
  66. if ($id !== false && !is_int($id))
  67. trigger_error('Argument 3 passed to '.__METHOD__.' must be a integer, '.gettype($id).' given', E_USER_ERROR);
  68. if ($row !== false && !is_array($row))
  69. trigger_error('Argument 4 passed to '.__METHOD__.' must be a Array, '.gettype($row).' given', E_USER_ERROR);
  70. $this->_label = $l;
  71. $this->_type = self::ITEM;
  72. if ($id === false) {
  73. $this->_id = $this->_addTag($this->_label, $this->_type, $row);
  74. $this->callClassCallback('addHook', $this);
  75. if ($row !== false)
  76. foreach($this->_cols as $n => $t)
  77. if (isset($row[$n]))
  78. $this->_set($n, $row[$n]);
  79. }
  80. else {
  81. if ($row !== false) $this->_fill($row);
  82. $this->_id = (int) $id;
  83. if (is_null($this->_label)) {
  84. $r = $this->_getTagBySystemID($id);
  85. $this->_label = $r['label'];
  86. }
  87. }
  88. }
  89. // }}}
  90. // {{{ addTagType
  91. /**
  92. * Ajout d'un type de tag au type d'item courant
  93. *
  94. * @param string $l label
  95. *
  96. * @return AIT_TagType
  97. */
  98. function addTagType($l, $r = false)
  99. {
  100. if (!is_string($l))
  101. trigger_error('Argument 1 passed to '.__METHOD__.' must be a String, '.gettype($l).' given', E_USER_ERROR);
  102. return new AIT_TagType($l, $this->_id, $this->getPDO(), false, $r);
  103. }
  104. function addTag($l, $r = false) { return $this->addTagType($l, $r); }
  105. // }}}
  106. // {{{ getTagType
  107. /**
  108. * Récupére un type de tag du type d'item courant
  109. *
  110. * @param string $l label
  111. *
  112. * @return AIT_TagType
  113. */
  114. function getTagType($l)
  115. {
  116. if (!is_string($l))
  117. trigger_error('Argument 1 passed to '.__METHOD__.' must be a String, '.gettype($l).' given', E_USER_ERROR);
  118. $sql = sprintf('
  119. SELECT tag.id id, label, type
  120. FROM %s tag
  121. LEFT JOIN %s b ON tag.id=b.tag_id
  122. WHERE label = ? and type = %s and item_id = ?
  123. LIMIT 0,1
  124. ',
  125. $this->getPDO()->tag(),
  126. $this->getPDO()->tagged(),
  127. self::TAG
  128. );
  129. self::timer();
  130. $stmt = $this->getPDO()->prepare($sql);
  131. $stmt->bindParam(1, $l, PDO::PARAM_STR);
  132. $stmt->bindParam(2, $this->_id, PDO::PARAM_INT);
  133. $stmt->execute();
  134. settype($this->_id, 'integer');
  135. if (($row = $stmt->fetch(PDO::FETCH_ASSOC))) {
  136. if (is_null($row['id'])) continue;
  137. settype($row['type'], 'integer');
  138. settype($row['id'], 'integer');
  139. $ret = new AIT_TagType($row['label'], $this->_id, $this->getPDO(), $row['id'], $row);
  140. }
  141. else $ret = null;
  142. $stmt->closeCursor();
  143. self::debug(self::timer(true), $sql, $l, $this->_id);
  144. return $ret;
  145. }
  146. function getTag($l) { return $this->getTagType($l); }
  147. // }}}
  148. // {{{ defTagType
  149. /**
  150. * Récupére un type tag associé au type d'item courant.
  151. * Si le tag n'existe pas il est automatiquement créé.
  152. *
  153. * @param string $l nom du tag
  154. *
  155. * @return AIT_TagType
  156. */
  157. function defTagType($l)
  158. {
  159. $ret = $this->getTagType($l);
  160. if (is_null($ret)) {
  161. $ret = new AIT_TagType($l, $this->_id, $this->getPDO());
  162. }
  163. return $ret;
  164. }
  165. function defTag($l) { return $this->defTagType($l); }
  166. // }}}
  167. // {{{ getTagTypes
  168. /**
  169. * Récupére tout les types de tags de l'item courant
  170. *
  171. * @param integer $offset décalage à parir du premier enregistrement
  172. * @param integer $lines nombre de lignes à retourner
  173. * @param integer $ordering flag permettant le tri
  174. * @param array $cols filtre sur les champs complémentaires
  175. *
  176. * @return AITResult
  177. */
  178. function getTagTypes($offset = null, $lines = null, $ordering = null, $cols = array())
  179. {
  180. if (!is_null($offset) && !is_int($offset))
  181. trigger_error('Argument 1 passed to '.__METHOD__.' must be a integer, '.gettype($offset).' given', E_USER_ERROR);
  182. if (!is_null($lines) && !is_int($lines))
  183. trigger_error('Argument 2 passed to '.__METHOD__.' must be a integer, '.gettype($lines).' given', E_USER_ERROR);
  184. if (!is_null($ordering) && !is_int($ordering))
  185. trigger_error('Argument 3 passed to '.__METHOD__.' must be a integer, '.gettype($ordering).' given', E_USER_ERROR);
  186. if (!is_array($cols))
  187. trigger_error('Argument 4 passed to '.__METHOD__.' must be a array'.gettype($cols).' given', E_USER_ERROR);
  188. $sql1 = 'SELECT id, label, prefix, suffix, buffer, scheme, language, score, frequency, type, content ';
  189. $sql2 = sprintf('
  190. FROM %1$s tagged
  191. LEFT JOIN %2$s tag ON tagged.tag_id=tag.id
  192. LEFT JOIN %3$s dat ON tag.dat_hash=dat.hash
  193. WHERE item_id = ?
  194. ',
  195. $this->getPDO()->tagged(),
  196. $this->getPDO()->tag(),
  197. $this->getPDO()->dat()
  198. );
  199. $sql = $sql1.$sql2.$this->filter($cols);
  200. self::sqler($sql, $offset, $lines, $ordering);
  201. if (($r = $this->callClassCallback(
  202. 'getTagTypesCache',
  203. $cid = self::str2cid($sql, $this->_id)
  204. )) !== false) return $r;
  205. self::timer();
  206. $stmt = $this->getPDO()->prepare($sql);
  207. $stmt->bindParam(1, $this->_id, PDO::PARAM_INT);
  208. $stmt->execute();
  209. settype($this->_id, 'integer');
  210. $ret = array();
  211. while (($row = $stmt->fetch(PDO::FETCH_ASSOC))) {
  212. if (is_null($row['id'])) continue;
  213. settype($row['id'], 'integer');
  214. $ret[] = new AIT_TagType($row['label'], $this->_id, $this->getPDO(), $row['id'], $row);
  215. }
  216. $stmt->closeCursor();
  217. self::debug(self::timer(true), $sql, $this->_id);
  218. $sql = 'SELECT COUNT(*) '.$sql2;
  219. $r = new AITResult($ret);
  220. $r->setQueryForTotal($sql, array($this->_id => PDO::PARAM_INT,), $this->getPDO());
  221. if (isset($cid))
  222. $this->callClassCallback('getTagTypesCache', $cid, $r);
  223. return $r;
  224. }
  225. function getTags($offset = null, $lines = null, $ordering = null) { return $this->getTagTypes($offset, $lines, $ordering); }
  226. // }}}
  227. // {{{ countTagTypes
  228. /**
  229. * Compte le nombre de tags associés au type d'item courant
  230. *
  231. * @return integer
  232. */
  233. function countTagTypes()
  234. {
  235. try {
  236. $sql = sprintf('
  237. SELECT count(*)
  238. FROM %s tagged
  239. WHERE item_id = ?
  240. ',
  241. $this->getPDO()->tagged()
  242. );
  243. self::timer();
  244. $stmt = $this->getPDO()->prepare($sql);
  245. $stmt->bindParam(1, $this->_id, PDO::PARAM_INT);
  246. $stmt->execute();
  247. settype($this->_id, 'integer');
  248. $c = (int)$stmt->fetchColumn(0);
  249. $stmt->closeCursor();
  250. self::debug(self::timer(true), $sql, $this->_id);
  251. return $c;
  252. }
  253. catch (PDOException $e) {
  254. self::catchError($e);
  255. }
  256. }
  257. function countTags() { return $this->countTagTypes(); }
  258. // }}}
  259. // {{{ newItem
  260. /**
  261. * Crée un item son label étant calculé automatiquement
  262. *
  263. * @return AIT_Item
  264. */
  265. function newItem()
  266. {
  267. $o = new AIT_Item('NEW', $this->_id, $this->getPDO());
  268. $o->ren('#'.$o->getSystemID());
  269. return $o;
  270. }
  271. // }}}
  272. // {{{ addItem
  273. /**
  274. * Ajout d'un item au type d'item courant
  275. *
  276. * @param string $l nom du nouveau item
  277. *
  278. * @return AIT_Item
  279. */
  280. function addItem($l, $r = false)
  281. {
  282. if (!is_string($l))
  283. trigger_error('Argument 1 passed to '.__METHOD__.' must be a String, '.gettype($l).' given', E_USER_ERROR);
  284. return new AIT_Item($l, $this->_id, $this->getPDO(), false, $r);
  285. }
  286. // }}}
  287. // {{{ getItem
  288. /**
  289. * Récupère un item
  290. *
  291. * @param string $l nom de l'item
  292. *
  293. * @return AIT_Item
  294. */
  295. function getItem($l)
  296. {
  297. if (!is_string($l))
  298. trigger_error('Argument 1 passed to '.__METHOD__.' must be a String, '.gettype($l).' given', E_USER_ERROR);
  299. $sql = sprintf('
  300. SELECT id, label, type
  301. FROM %s tag
  302. WHERE label = ? AND type = ?
  303. LIMIT 0,1
  304. ',
  305. $this->getPDO()->tag()
  306. );
  307. if (($r = $this->callClassCallback(
  308. 'getItemCache',
  309. $cid = self::str2cid($l, $this->_id)
  310. )) !== false) return $r;
  311. self::timer();
  312. $stmt = $this->getPDO()->prepare($sql);
  313. $stmt->bindParam(1, $l, PDO::PARAM_STR);
  314. $stmt->bindParam(2, $this->_id, PDO::PARAM_INT);
  315. $stmt->execute();
  316. settype($this->_id, 'integer');
  317. if (($row = $stmt->fetch(PDO::FETCH_ASSOC))) {
  318. if (is_null($row['id'])) continue;
  319. settype($row['type'], 'integer');
  320. settype($row['id'], 'integer');
  321. $ret = new AIT_Item($row['label'], $this->_id, $this->getPDO(), $row['id'], $row);
  322. }
  323. else $ret = null;
  324. $id = (int)$stmt->fetchColumn(0);
  325. $stmt->closeCursor();
  326. self::debug(self::timer(true), $sql, $l, $this->_id);
  327. if (isset($cid))
  328. $this->callClassCallback('getItemCache', $cid, $ret);
  329. return $ret;
  330. }
  331. // }}}
  332. // {{{ defItem
  333. /**
  334. * Récupére un item associé au type d'item courant.
  335. * Si l'item n'existe pas il est automatiquement créé.
  336. *
  337. * @param string $l nom de l'item
  338. *
  339. * @return AIT_Item
  340. */
  341. function defItem($l)
  342. {
  343. $ret = $this->getItem($l);
  344. if (is_null($ret))
  345. $ret = new AIT_Item($l, $this->_id, $this->getPDO());
  346. return $ret;
  347. }
  348. // }}}
  349. // {{{ getItems
  350. /**
  351. * Récupére tous les items du type d'item courant
  352. *
  353. * @param integer $offset décalage à parir du premier enregistrement
  354. * @param integer $lines nombre de lignes à retourner
  355. * @param integer $ordering flag permettant le tri
  356. * @param array $cols filtre sur les champs complémentaires
  357. *
  358. * @return AITResult
  359. */
  360. function getItems($offset = null, $lines = null, $ordering = null, $cols = array())
  361. {
  362. if (!is_null($offset) && !is_int($offset))
  363. trigger_error('Argument 1 passed to '.__METHOD__.' must be a integer, '.gettype($offset).' given', E_USER_ERROR);
  364. if (!is_null($lines) && !is_int($lines))
  365. trigger_error('Argument 2 passed to '.__METHOD__.' must be a integer, '.gettype($offset).' given', E_USER_ERROR);
  366. if (!is_null($ordering) && !is_int($ordering))
  367. trigger_error('Argument 3 passed to '.__METHOD__.' must be a integer, '.gettype($ordering).' given', E_USER_ERROR);
  368. if (!is_array($cols))
  369. trigger_error('Argument 4 passed to '.__METHOD__.' must be a array'.gettype($cols).' given', E_USER_ERROR);
  370. $sql1 = 'SELECT id, label, prefix, suffix, buffer, scheme, language, score, frequency, content ';
  371. $sql2 = sprintf('
  372. FROM %s tag
  373. LEFT JOIN %s dat ON tag.dat_hash=dat.hash
  374. WHERE type = ?
  375. ',
  376. $this->getPDO()->tag(),
  377. $this->getPDO()->dat()
  378. );
  379. $sql = $sql1.$sql2.$this->filter($cols);
  380. self::sqler($sql, $offset, $lines, $ordering);
  381. if (($r = $this->callClassCallback(
  382. 'getItemsCache',
  383. $cid = self::str2cid($sql, $this->_id)
  384. )) !== false) return $r;
  385. self::timer();
  386. $stmt = $this->getPDO()->prepare($sql);
  387. $stmt->bindParam(1, $this->_id, PDO::PARAM_INT);
  388. $stmt->execute();
  389. settype($this->_id, 'integer');
  390. $ret = array();
  391. while (($row = $stmt->fetch(PDO::FETCH_ASSOC))) {
  392. if (is_null($row['id'])) continue;
  393. settype($row['id'], 'integer');
  394. $ret[] = new AIT_Item($row['label'], $this->_id, $this->getPDO(), $row['id'], $row);
  395. }
  396. $stmt->closeCursor();
  397. self::debug(self::timer(true), $sql, $this->_id);
  398. $sql = 'SELECT COUNT(*) '.$sql2;
  399. $r = new AITResult($ret);
  400. $r->setQueryForTotal($sql, array($this->_id => PDO::PARAM_INT,), $this->getPDO());
  401. if (isset($cid))
  402. $this->callClassCallback('getItemsCache', $cid, $r);
  403. return $r;
  404. }
  405. // }}}
  406. // {{{ fetchItems
  407. /**
  408. * Récupére les items possédant un ou plusieurs tags donnée en paramètres
  409. *
  410. * @param ArrayObject $tags Tableau de tag
  411. * @param integer $offset décalage à parir du premier enregistrement
  412. * @param integer $lines nombre de lignes à retourner
  413. * @param integer $ordering flag permettant le tri
  414. * @param array $cols filtre sur les champs complémentaires
  415. *
  416. * @return AITResult
  417. */
  418. function fetchItems(ArrayObject $tags, $offset = null, $lines = null, $ordering = null, $cols = array())
  419. {
  420. if (!is_null($offset) && !is_int($offset))
  421. trigger_error('Argument 2 passed to '.__METHOD__.' must be a integer, '.gettype($offset).' given', E_USER_ERROR);
  422. if (!is_null($lines) && !is_int($lines))
  423. trigger_error('Argument 3 passed to '.__METHOD__.' must be a integer, '.gettype($lines).' given', E_USER_ERROR);
  424. if (!is_null($ordering) && !is_int($ordering))
  425. trigger_error('Argument 4 passed to '.__METHOD__.' must be a integer, '.gettype($ordering).' given', E_USER_ERROR);
  426. if (!is_array($cols))
  427. trigger_error('Argument 4 passed to '.__METHOD__.' must be a array'.gettype($cols).' given', E_USER_ERROR);
  428. $n = 0;
  429. $w = '';
  430. if ($tags->count() == 0) return new AITResult(array());
  431. foreach($tags as $tag) {
  432. if (! $tag instanceof AIT_Tag) {
  433. trigger_error('Line #'.($n + 1).' of Argument 1 passed to '.__METHOD__.' must be a instance of AIT_Tag, '.gettype($tag).' given and ignored', E_USER_NOTICE);
  434. continue;
  435. }
  436. if (empty($w)) {
  437. $w .= sprintf(' tagged.tag_id = %s ', $tag->getSystemID());
  438. }
  439. else {
  440. $w .= sprintf(' AND EXISTS (SELECT null FROM %s t WHERE t.item_id = tagged.item_id and t.tag_id = %s)',
  441. $this->getPDO()->tagged(),
  442. $tag->getSystemID()
  443. );
  444. }
  445. $n++;
  446. }
  447. if ($n === 0) return new AITResult(array());
  448. $sql1 = 'SELECT DISTINCT id, label, prefix, suffix, buffer, scheme, language, score, frequency, type, content ';
  449. $sql2 = sprintf('
  450. FROM %s tagged
  451. LEFT JOIN %s tag ON tagged.item_id = tag.id
  452. LEFT JOIN %s dat ON tag.dat_hash=dat.hash
  453. WHERE %s AND type = ?
  454. ',
  455. $this->getPDO()->tagged(),
  456. $this->getPDO()->tag(),
  457. $this->getPDO()->dat(),
  458. $w
  459. );
  460. $sql = $sql1.$sql2.$this->filter($cols);
  461. self::sqler($sql, $offset, $lines, $ordering);
  462. if (($r = $this->callClassCallback(
  463. 'fetchItemsCache',
  464. $cid = self::str2cid($sql, $this->_id)
  465. )) !== false) return $r;
  466. self::timer();
  467. $stmt = $this->getPDO()->prepare($sql);
  468. $stmt->bindParam(1, $this->_id, PDO::PARAM_INT);
  469. $stmt->execute();
  470. settype($this->_id, 'integer');
  471. $ret = array();
  472. while (($row = $stmt->fetch(PDO::FETCH_ASSOC))) {
  473. if (is_null($row['id'])) continue;
  474. settype($row['type'], 'integer');
  475. settype($row['id'], 'integer');
  476. $ret[] = new AIT_Item($row['label'], $row['type'], $this->getPDO(), $row['id'], $row);
  477. }
  478. $stmt->closeCursor();
  479. self::debug(self::timer(true), $sql, $this->_id);
  480. $sql = 'SELECT count(DISTINCT id) '.$sql2;
  481. $r = new AITResult($ret, $this->getPDO());
  482. if ($tags->count() > 1) {
  483. $r->setQueryForTotal($sql, array($this->_id => PDO::PARAM_INT,));
  484. }
  485. else {
  486. // Pour un seul tag il est intule de faire un "count"
  487. // alors que sa frequence contient le nombre exacte d'items
  488. $r->setTotal($tags->offsetGet(0)->countItems());
  489. }
  490. if (isset($cid))
  491. $this->callClassCallback('fetchItemsCache', $cid, $r);
  492. return $r;
  493. }
  494. // }}}
  495. // {{{ searchItems
  496. /**
  497. * Recherche des items du type courant à partir des tags
  498. *
  499. * Important : Ne sont ramenés que des items possédant des tags.
  500. *
  501. * @param string $query requete (le format dépend de la search_callback) sans callback c'est du SQL
  502. * @param integer $offset décalage à parir du premier enregistrement
  503. * @param integer $lines nombre de lignes à retourner
  504. * @param integer $ordering flag permettant le tri
  505. * @param array $cols filtre sur les champs complémentaires
  506. *
  507. * @return AITResult
  508. */
  509. function searchItems($query, $offset = null, $lines = null, $ordering = null, $cols = array())
  510. {
  511. if (!is_null($offset) && !is_int($offset))
  512. trigger_error('Argument 2 passed to '.__METHOD__.' must be a integer, '.gettype($offset).' given', E_USER_ERROR);
  513. if (!is_null($lines) && !is_int($lines))
  514. trigger_error('Argument 3 passed to '.__METHOD__.' must be a integer, '.gettype($lines).' given', E_USER_ERROR);
  515. if (!is_null($ordering) && !is_int($ordering))
  516. trigger_error('Argument 4 passed to '.__METHOD__.' must be a integer, '.gettype($ordering).' given', E_USER_ERROR);
  517. if (!is_array($cols))
  518. trigger_error('Argument 5 passed to '.__METHOD__.' must be a array'.gettype($cols).' given', E_USER_ERROR);
  519. if ($this->isClassCallback('searchItemsHook'))
  520. $query = $this->callClassCallback('searchItemsHook', $query, $this);
  521. if ($query !== '' and $query !== false) $query = 'AND '.$query;
  522. $sql1 = 'SELECT DISTINCT item.id id, item.label label, item.prefix prefix, item.suffix suffix, item.buffer buffer, item.scheme scheme, item.language language, item.score score, item.frequency frequency, content';
  523. $sql2 = sprintf('
  524. FROM %1$s tag
  525. LEFT JOIN %2$s b ON tag.type=b.tag_id
  526. LEFT JOIN %2$s d ON tag.id=d.tag_id
  527. LEFT JOIN %1$s item ON d.item_id=item.id
  528. LEFT JOIN %3$s dat ON tag.dat_hash=dat.hash
  529. WHERE b.item_id = item.type AND item.type = ? %4$s
  530. ',
  531. $this->getPDO()->tag(),
  532. $this->getPDO()->tagged(),
  533. $this->getPDO()->dat(),
  534. $query
  535. );
  536. $sql = $sql1.$sql2.$this->filter($cols);
  537. self::sqler($sql, $offset, $lines, $ordering);
  538. if (($r = $this->callClassCallback(
  539. 'searchItemsCache',
  540. $cid = self::str2cid($sql, $this->_id)
  541. )) !== false) return $r;
  542. self::timer();
  543. $stmt = $this->getPDO()->prepare($sql);
  544. $stmt->bindParam(1, $this->_id, PDO::PARAM_INT);
  545. $stmt->execute();
  546. settype($this->_id, 'integer');
  547. $ret = array();
  548. while (($row = $stmt->fetch(PDO::FETCH_ASSOC))) {
  549. if (is_null($row['id'])) continue;
  550. settype($row['id'], 'integer');
  551. $ret[] = new AIT_Item($row['label'], $this->_id, $this->getPDO(), $row['id'], $row);
  552. }
  553. $stmt->closeCursor();
  554. self::debug(self::timer(true), $sql, $this->_id);
  555. $sql = 'SELECT COUNT(DISTINCT item.id) '.$sql2;
  556. $r = new AITResult($ret);
  557. $r->setQueryForTotal($sql, array($this->_id => PDO::PARAM_INT,), $this->getPDO());
  558. if (isset($cid))
  559. $this->callClassCallback('searchItemsCache', $cid, $r);
  560. return $r;
  561. }
  562. // }}}
  563. // {{{ getItemBySystemID
  564. /**
  565. * Récupère un Item
  566. *
  567. * @param integer $i
  568. *
  569. * @return AIT_Item
  570. */
  571. function getItemBySystemID($i)
  572. {
  573. if (!is_integer($i))
  574. trigger_error('Argument 1 passed to '.__METHOD__.' must be a integer, '.gettype($i).' given', E_USER_ERROR);
  575. $row = $this->_getTagBySystemID($i);
  576. if (is_array($row)) {
  577. return new AIT_Item($row['label'], $this->_id, $this->getPDO(), $row['id']);
  578. }
  579. }
  580. // }}}
  581. // {{{ queryItems
  582. /**
  583. * On recherche des items associés au TYPE d'ITEM courant à partir d'un objet AITQuery
  584. *
  585. * @param AITQuery $query requete
  586. * @param integer $offset décalage à parir du premier enregistrement
  587. * @param integer $lines nombre de lignes à retourner
  588. * @param integer $ordering flag permettant le tri
  589. * @param array $cols filtre sur les champs complémentaires
  590. *
  591. * @return AITResult
  592. */
  593. function queryItems(AITQuery $query, $offset = null, $lines = null, $ordering = null, $cols = array())
  594. {
  595. if (!is_null($offset) && !is_int($offset))
  596. trigger_error('Argument 2 passed to '.__METHOD__.' must be a integer, '.gettype($offset).' given', E_USER_ERROR);
  597. if (!is_null($lines) && !is_int($lines))
  598. trigger_error('Argument 3 passed to '.__METHOD__.' must be a integer, '.gettype($lines).' given', E_USER_ERROR);
  599. if (!is_null($ordering) && !is_int($ordering))
  600. trigger_error('Argument 4 passed to '.__METHOD__.' must be a integer, '.gettype($ordering).' given', E_USER_ERROR);
  601. if (!is_array($cols))
  602. trigger_error('Argument 4 passed to '.__METHOD__.' must be a array'.gettype($cols).' given', E_USER_ERROR);
  603. $w = $query->getSQL();
  604. $sql1 = 'SELECT id, label, prefix, suffix, buffer, scheme, language, score, frequency, type, content ';
  605. $sql2 = sprintf('
  606. FROM (%s) temp
  607. LEFT JOIN %s tag ON temp.item_id = tag.id
  608. LEFT JOIN %s dat ON tag.dat_hash=dat.hash
  609. WHERE type = ?
  610. ',
  611. $w,
  612. $this->getPDO()->tag(),
  613. $this->getPDO()->dat()
  614. );
  615. $sql = $sql1.$sql2.$this->filter($cols);
  616. self::sqler($sql, $offset, $lines, $ordering);
  617. if (($r = $this->callClassCallback(
  618. 'queryItemsCache',
  619. $cid = self::str2cid($sql, $this->_id)
  620. )) !== false) return $r;
  621. self::timer();
  622. $stmt = $this->getPDO()->prepare($sql);
  623. $stmt->bindParam(1, $this->_id, PDO::PARAM_INT);
  624. $stmt->execute();
  625. settype($this->_id, 'integer');
  626. $ret = array();
  627. while (($row = $stmt->fetch(PDO::FETCH_ASSOC))) {
  628. if (is_null($row['id'])) continue;
  629. settype($row['type'], 'integer');
  630. settype($row['id'], 'integer');
  631. $ret[] = new AIT_Item($row['label'], $row['type'], $this->getPDO(), $row['id'], $row);
  632. }
  633. $stmt->closeCursor();
  634. self::debug(self::timer(true), $sql, $this->_id);
  635. $sql = 'SELECT COUNT(*) '.$sql2;
  636. $r = new AITResult($ret);
  637. $r->setQueryForTotal($sql, array($this->_id => PDO::PARAM_INT,), $this->getPDO());
  638. if (isset($cid))
  639. $this->callClassCallback('queryItemsCache', $cid, $r);
  640. return $r;
  641. }
  642. // }}}
  643. // {{{ getAll
  644. /**
  645. * Récupére Tous les types d'items de la base
  646. *
  647. * @param PDOAIT $pdo pointeur sur la base de données
  648. * @param integer $offset décalage à parir du premier enregistrement
  649. * @param integer $lines nombre de lignes à retourner
  650. * @param integer $ordering flag permettant le tri
  651. *
  652. * @return AITResult
  653. */
  654. static function getAll(PDOAIT $pdo, $offset = null, $lines = null, $ordering = null)
  655. {
  656. if (!is_null($offset) && !is_int($offset))
  657. trigger_error('Argument 2 passed to '.__METHOD__.' must be a integer, '.gettype($offset).' given', E_USER_ERROR);
  658. if (!is_null($lines) && !is_int($lines))
  659. trigger_error('Argument 3 passed to '.__METHOD__.' must be a integer, '.gettype($lines).' given', E_USER_ERROR);
  660. if (!is_null($ordering) && !is_int($ordering))
  661. trigger_error('Argument 4 passed to '.__METHOD__.' must be a integer, '.gettype($ordering).' given', E_USER_ERROR);
  662. $sql1 = 'SELECT id, label, prefix, suffix, buffer, scheme, language, score, frequency, content';
  663. $sql2 = sprintf('
  664. FROM %s tag
  665. LEFT JOIN %s dat ON tag.dat_hash=dat.hash
  666. WHERE type = 1
  667. ',
  668. $pdo->tag(),
  669. $pdo->dat()
  670. );
  671. $sql = $sql1.$sql2;
  672. self::sqler($sql, $offset, $lines, $ordering);
  673. $stmt = $pdo->prepare($sql);
  674. $stmt->execute();
  675. $ret = array();
  676. while (($row = $stmt->fetch(PDO::FETCH_ASSOC))) {
  677. if (is_null($row['id'])) continue;
  678. settype($row['type'], 'integer');
  679. settype($row['id'], 'integer');
  680. $ret[] = new AIT_ItemType($row['label'], $pdo, $row['id'], $row);
  681. }
  682. $stmt->closeCursor();
  683. $sql = 'SELECT COUNT(*) '.$sql2;
  684. $r = new AITResult($ret);
  685. $r->setQueryForTotal($sql, array(), $pdo);
  686. return $r;
  687. }
  688. // }}}
  689. // {{{ countItems
  690. /**
  691. * Compte le nombre d'items du type d'item courant
  692. *
  693. * @return integer
  694. */
  695. function countItems()
  696. {
  697. return (int) $this->_get('frequency', true);
  698. }
  699. // }}}
  700. // {{{ del
  701. /**
  702. * Suppression de l'élement courrant
  703. */
  704. public function del()
  705. {
  706. $items = $this->getItems();
  707. foreach($items as $item) {
  708. $item->del(true);
  709. }
  710. $tags = $this->getTags();
  711. foreach($tags as $tag) {
  712. $tag->del(true);
  713. }
  714. $this->_rmTag();
  715. }
  716. // }}}
  717. // {{{ select
  718. /**
  719. * Selectionne des items du type courant à partir des items eux-même
  720. *
  721. * @param string $query requete (le format dépend de la search_callback) sans callback c'est du SQL
  722. * @param integer $offset décalage à parir du premier enregistrement
  723. * @param integer $lines nombre de lignes à retourner
  724. * @param integer $ordering flag permettant le tri
  725. * @param array $cols filtre sur les champs complémentaires
  726. *
  727. * @return AITResult
  728. */
  729. function selectItems($query, $offset = null, $lines = null, $ordering = null, $cols = array())
  730. {
  731. if (!is_null($offset) && !is_int($offset))
  732. trigger_error('Argument 2 passed to '.__METHOD__.' must be a integer, '.gettype($offset).' given', E_USER_ERROR);
  733. if (!is_null($lines) && !is_int($lines))
  734. trigger_error('Argument 3 passed to '.__METHOD__.' must be a integer, '.gettype($lines).' given', E_USER_ERROR);
  735. if (!is_null($ordering) && !is_int($ordering))
  736. trigger_error('Argument 4 passed to '.__METHOD__.' must be a integer, '.gettype($ordering).' given', E_USER_ERROR);
  737. if (!is_array($cols))
  738. trigger_error('Argument 5 passed to '.__METHOD__.' must be a array'.gettype($cols).' given', E_USER_ERROR);
  739. if ($this->isClassCallback('selectItemsHook'))
  740. $query = $this->callClassCallback('selectItemsHook', $query, $this);
  741. if ($query !== '' and $query !== false) $query = 'AND '.$query;
  742. $sql1 = 'SELECT DISTINCT id, label, prefix, suffix, buffer, scheme, language, score, frequency, content';
  743. $sql2 = sprintf('
  744. FROM %1$s item
  745. LEFT JOIN %2$s dat ON item.dat_hash=dat.hash
  746. WHERE item.type = ? %3$s
  747. ',
  748. $this->getPDO()->tag(),
  749. $this->getPDO()->dat(),
  750. $query
  751. );
  752. $sql = $sql1.$sql2.$this->filter($cols, 'item');
  753. self::sqler($sql, $offset, $lines, $ordering);
  754. if (($r = $this->callClassCallback(
  755. 'selectItemsCache',
  756. $cid = self::str2cid($sql, $this->_id)
  757. )) !== false) return $r;
  758. self::timer();
  759. $stmt = $this->getPDO()->prepare($sql);
  760. $stmt->bindParam(1, $this->_id, PDO::PARAM_INT);
  761. $stmt->execute();
  762. settype($this->_id, 'integer');
  763. $ret = array();
  764. while (($row = $stmt->fetch(PDO::FETCH_ASSOC))) {
  765. if (is_null($row['id'])) continue;
  766. settype($row['id'], 'integer');
  767. $ret[] = new AIT_Item($row['label'], $this->_id, $this->getPDO(), $row['id'], $row);
  768. }
  769. $stmt->closeCursor();
  770. self::debug(self::timer(true), $sql, $this->_id, $this->_id);
  771. $sql = 'SELECT COUNT(*) '.$sql2;
  772. $r = new AITResult($ret);
  773. $r->setQueryForTotal($sql, array($this->_id => PDO::PARAM_INT,), $this->getPDO());
  774. if (isset($cid))
  775. $this->callClassCallback('selectItemsCache', $cid, $r);
  776. return $r;
  777. }
  778. // }}}
  779. // {{{ __get
  780. /**
  781. * Retourne un type de tag associé
  782. *
  783. * @param string $name
  784. *
  785. * @return AIT_TypeTag
  786. */
  787. public function __get($name) {
  788. if (is_null($name) or $name == '')
  789. return null;
  790. if (!isset($this->TagTypes[$name]))
  791. $this->TagTypes[$name] = $this->defTag($name);
  792. return $this->TagTypes[$name];
  793. }
  794. // }}}
  795. }