/AIT.php
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
- <?php
- // vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 encoding=utf-8 fdm=marker :
- // {{{ Licence
- // +--------------------------------------------------------------------------+
- // | AIT - All is Tag |
- // +--------------------------------------------------------------------------+
- // | Copyright (C) 2009 Nicolas Thouvenin |
- // +--------------------------------------------------------------------------+
- // | This library is free software; you can redistribute it and/or |
- // | modify it under the terms of the GNU General Public License |
- // | as published by the Free Software Foundation; either version 2 |
- // | of the License, or (at your option) any later version. |
- // | |
- // | This program is distributed in the hope that it will be useful, |
- // | but WITHOUT ANY WARRANTY; without even the implied warranty of |
- // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
- // | General Public License for more details. |
- // | |
- // | You should have received a copy of the GNU General Public License |
- // | along with this library; if not, write to the Free Software |
- // | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
- // +--------------------------------------------------------------------------+
- // }}}
- /**
- * @category AIT
- * @package AIT
- * @author Nicolas Thouvenin <nthouvenin@gmail.com>
- * @copyright 2009 Nicolas Thouvenin
- * @license http://opensource.org/licenses/lgpl-license.php LGPL
- * @version SVN: $Id$
- * @link http://ait.touv.fr/
- * */
- /**
- * Dépendances
- */
- require_once 'AIT/ItemType.php';
- require_once 'AIT/Item.php';
- require_once 'AIT/TagType.php';
- require_once 'AIT/Tag.php';
- /**
- * Objet représantant un schéma au sens AIT
- *
- * @category AIT
- * @package AIT
- * @author Nicolas Thouvenin <nthouvenin@gmail.com>
- * @copyright 2009 Nicolas Thouvenin
- * @license http://opensource.org/licenses/lgpl-license.php LGPL
- * @link http://ait.touv.fr/
- */
- class AITSchema {
- private $_pointers = array();
- // {{{ __construct
- /**
- * purifie une chaine de carctère représantant un type en une chaine compatible php
- *
- * @param PDOAIT connexion à la base
- * @param string Type d'Item
- * @param array tableau de type de tag
- */
- function __construct(PDOAIT $pdo, $name, array $attributs)
- {
- $n = $this->_toVarname($name);
- $this->_pointers[$n] = new AIT_ItemType($name, $pdo);
- foreach($attributs as $attr) {
- $a = $this->_toVarname($attr);
- $this->_pointers[$a] = $this->_pointers[$n]->getTag($attr);
- if (is_null($this->_pointers[$a])) {
- $this->_pointers[$a] = $this->_pointers[$n]->addTag($attr);
- }
- }
- }
- // }}}
- // {{{ _toVarname
- /**
- * purifie une chaine de carctère représantant un type en une chaine compatible php
- *
- * @param string $name
- *
- * @return string
- */
- private function _toVarname($s)
- {
- return '_'.md5(trim(strtolower($s)));
- }
- // }}}
- // {{{ __get
- /**
- * Retroune un objet AIT
- *
- * @param string $name
- *
- * @return mixed
- */
- public function __get($name) {
- $n = $this->_toVarname($name);
- if (array_key_exists($n, $this->_pointers))
- return $this->_pointers[$n];
- else
- return null;
- }
- // }}}
- }
- /**
- * Objet de connexion à la base
- *
- * @category AIT
- * @package AIT
- * @author Nicolas Thouvenin <nthouvenin@gmail.com>
- * @copyright 2009 Nicolas Thouvenin
- * @license http://opensource.org/licenses/lgpl-license.php LGPL
- * @link http://ait.touv.fr/
- */
- class PDOAIT extends PDO
- {
- private $_options = array(
- 'dsn' => '',
- 'username' => '',
- 'password' => '',
- 'drvropts' => array(),
- 'prefix' => '',
- 'opt' => 'opt',
- 'tag' => 'tag',
- 'tagged' => 'rel',
- 'dat' => 'dat',
- 'callbacks' => array(),
- 'extends' => array(),
- );
- // {{{ __construct
- /**
- * Constructeur
- *
- * @param string $dsn chaine de connexion
- * @param string $username user de connexion
- * @param string $password mot de passe de connexion
- * @param array $driver_options options pour pdo
- */
- public function __construct($dsn, $username = null, $password = null, $driver_options = null)
- {
- parent::__construct($dsn, $username, $password, $driver_options);
- $this->setOption('dsn', $dsn);
- $this->setOption('username', $username);
- $this->setOption('password', $password);
- $this->setOption('drvropts', $driver_options);
- }
- // }}}
- // {{{ extendsWith
- /**
- * Ajoute à AIT un module complémentaire
- *
- * @param AIT_Extended $o
- *
- * @return PDOAIT
- */
- public function extendWith(AIT_Extended $o)
- {
- $o->register($this);
- $this->_options['extends'][] = $o;
- return $this;
- }
- // }}}
- // {{{ getOption
- /**
- * renvoit la valeur d'une option
- *
- * @param string $name name
- * @return string
- */
- public function getOption($n)
- {
- if (isset($this->_options[$n])) {
- return $this->_options[$n];
- }
- }
- // }}}
- // {{{ getOptions
- /**
- * Retourne les options
- *
- * @param array $a tableau d'option
- */
- public function getOptions()
- {
- return $this->_options;
- }
- // }}}
- // {{{ setOption
- /**
- * Fixe une option
- *
- * @param string $name nom
- * @param string $value valeur
- * @return string
- */
- public function setOption($n, $v)
- {
- if (isset($this->_options[$n]) && !is_null($v)) {
- $func = array($this, 'setOption'.ucfirst($n));
- if (is_callable($func)) {
- call_user_func($func, $v);
- }
- else {
- $this->_options[$n] = $v;
- }
- }
- }
- // }}}
- // {{{ setOption
- /**
- * Fixe l'option "callbacks"
- *
- * @param string $value valeur
- * @return string
- */
- public function setOptionCallbacks($v)
- {
- reset($v);
- while (list($k, ) = each($v)) {
- if (!isset($this->_options['callbacks'][$k])) {
- $this->_options['callbacks'][$k] = $v[$k];
- }
- elseif (!is_array($this->_options['callbacks'][$k])) {
- $this->_options['callbacks'][$k] = $v[$k];
- }
- elseif (is_array($this->_options['callbacks'][$k])) {
- $this->_options['callbacks'][$k] = array_merge($this->_options['callbacks'][$k], $v[$k]);
- }
- }
- }
- // }}}
- // {{{ setOptions
- /**
- * Fixe les options
- *
- * @param array $a tableau d'option
- */
- public function setOptions(array $a)
- {
- foreach($a as $n => $v) $this->setOption($n, $v);
- }
- // }}}
- // {{{ opt
- /**
- * Renvoit le nom de la table ait
- *
- * @return string
- */
- public function opt()
- {
- return $this->_options['prefix'].$this->_options['opt'];
- }
- // }}}
- // {{{ tag
- /**
- * Renvoit le nom de la table tag
- *
- * @param boolean
- * @return string
- */
- public function tag($crud = false)
- {
- return $this->_options['prefix'].$this->_options['tag'];
- }
- // }}}
- // {{{ tagged
- /**
- * Renvoit le nom de la table tagged
- *
- * @param boolean
- * @return string
- */
- public function tagged($crud = false)
- {
- return $this->_options['prefix'].$this->_options['tagged'];
- }
- // }}}
- // {{{ dat
- /**
- * Renvoit le nom de la table dat
- *
- * @param boolean
- * @return string
- */
- public function dat($crud = false)
- {
- return $this->_options['prefix'].$this->_options['dat'];
- }
- // }}}
- // {{{ checkup
- /**
- * Controle la validité de la structure de données
- *
- * @param boolean $init Lance ou non l'initaliasation automatatique (par défaut true)
- *
- * @return boolean
- */
- public function checkup($init = true)
- {
- try {
- $sql = sprintf('
- SELECT count(*) n FROM %s WHERE label=\'tag\' or label=\'item\' LIMIT 0,1;
- ',
- $this->tag());
- $stmt = $this->query($sql);
- $c = (int)$stmt->fetchColumn(0);
- $stmt->closeCursor();
- if ($c === 0 and $init) $this->_initData();
- elseif ($c === 0 and !$init) return false;
- }
- catch (PDOException $e) {
- if ($init) $this->_initTable();
- else return false;
- }
- return true;
- }
- // }}}
- // {{{ registerSchema
- /**
- * Enregistre un schema AIT (soit un type d'item associé à des types de tags)
- *
- * @param string Type d'Item
- * @param array tableau de type de tag
- *
- * @return AITSchema
- */
- public function registerSchema($name, array $attr)
- {
- return new AITSchema($this, $name, $attr);
- }
- // }}}
- // {{{ _initTable
- /**
- * Initialise la structure de données
- */
- private function _initTable()
- {
- try {
- $driver = strtolower($this->getAttribute(PDO::ATTR_DRIVER_NAME));
- switch ($driver) {
- case 'mysql':
- $this->exec(sprintf("
- CREATE TABLE %s (
- id INTEGER(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
- label VARCHAR(200) COLLATE latin1_general_cs NOT NULL,
- frequency INTEGER(10) UNSIGNED NOT NULL default '0',
- type INTEGER(11) UNSIGNED NOT NULL default '0',
- updated timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
- created timestamp NOT NULL default '0000-00-00 00:00:00',
- score INTEGER(10) NOT NULL default '0',
- dat_hash BINARY(20) NULL,
- language VARCHAR(5) COLLATE latin1_general_cs NULL,
- scheme VARCHAR(10) COLLATE latin1_general_cs NULL,
- prefix VARCHAR(50) COLLATE latin1_general_cs NULL,
- suffix VARCHAR(50) COLLATE latin1_general_cs NULL,
- buffer VARCHAR(200) COLLATE latin1_general_cs NULL,
- INDEX (label),
- FULLTEXT (buffer),
- INDEX (score),
- INDEX (type),
- INDEX (type,created),
- INDEX (type,updated),
- INDEX (type,score),
- INDEX (type,frequency)
- ) ENGINE=MYISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_cs;
- ", $this->tag(true)));
- $this->exec(sprintf("
- CREATE TABLE %s (
- tag_id INTEGER(11) UNSIGNED NOT NULL,
- item_id INTEGER(11) UNSIGNED NOT NULL,
- rank INTEGER(11) NOT NULL default '0',
- PRIMARY KEY (tag_id, item_id),
- INDEX (tag_id),
- INDEX (item_id)
- ) ENGINE=MYISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_cs;
- ", $this->tagged(true)));
- $this->exec(sprintf("
- CREATE TABLE %s (
- hash BINARY(20) NOT NULL,
- content TEXT COLLATE latin1_general_cs NOT NULL,
- PRIMARY KEY (hash),
- FULLTEXT (content)
- ) ENGINE=MYISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_cs;
- ", $this->dat(true)));
- $this->exec(sprintf("
- CREATE TABLE %s (
- name VARCHAR(10) COLLATE latin1_general_cs NOT NULL,
- value VARCHAR(200) COLLATE latin1_general_cs NOT NULL,
- PRIMARY KEY (name)
- ) ENGINE=MYISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_cs;
- ", $this->opt(true)));
- $this->exec(sprintf("
- INSERT INTO %s VALUES ('version', '%s');
- ", $this->opt(true), AIT::VERSION));
- $this->_initData();
- break;
- default:
- throw new Exception($driver.' not supported by AIT.');
- }
- }
- catch (PDOException $e) {
- AIT::catchError($e);
- }
- }
- // }}}
- // {{{ _initData
- /**
- * Initialise les données obligatoires
- * @param PDO $this Pointeur sur la base de données
- */
- private function _initData()
- {
- try {
- $this->exec(sprintf(
- "INSERT INTO %s (id, label, created) VALUES (%s, 'item', now());",
- $this->tag(true),
- AIT::ITEM
- ));
- $this->exec(sprintf(
- "INSERT INTO %s (id, label, created) VALUES (%s, 'tag', now());",
- $this->tag(true),
- AIT::TAG
- ));
- }
- catch (PDOException $e) {
- AIT::catchError($e);
- }
- }
- // }}}
- }
- /**
- * Objet Racine
- *
- * @category AIT
- * @package AIT
- * @author Nicolas Thouvenin <nthouvenin@gmail.com>
- * @copyright 2009 Nicolas Thouvenin
- * @license http://opensource.org/licenses/lgpl-license.php LGPL
- * @link http://ait.touv.fr/
- */
- abstract class AITRoot
- {
- /**
- * @var PDOAIT
- */
- private $_pdo;
- /**
- * @var array
- */
- protected $_pdo_opt;
- // {{{ getPDO
- /**
- * Renvoit l'objet PDO utilisé
- *
- * @return PDO
- */
- public function getPDO()
- {
- if (is_null($this->_pdo)) {
- $this->_pdo = new PDOAIT(
- $this->_pdo_opt['dsn'],
- $this->_pdo_opt['username'],
- $this->_pdo_opt['password'],
- $this->_pdo_opt['drvropts']
- );
- }
- $this->_pdo->setOptions($this->_pdo_opt);
- return $this->_pdo;
- }
- // }}}
- // {{{ setPDO
- /**
- * Fixe l'objet PDO utilisé
- *
- * @param PDOAIT
- */
- public function setPDO(PDOAIT $pdo)
- {
- $this->_pdo = $pdo;
- $this->_pdo_opt = $pdo->getOptions();
- }
- // }}}
- // {{{ __sleep
- /**
- * Avant serialization
- *
- */
- public function __sleep ()
- {
- $this->_pdo_opt = $this->getPDO()->getOptions();
- $vars = array_keys(get_object_vars($this));
- unset($vars[array_search('_pdo', $vars)]);
- return $vars;
- }
- // }}}
- }
- /**
- * Classe principale.
- * Utilisé de manière statique, elle gére la connection à la base et son initialisation.
- * Dans les autres cas elle sert de classe abstraite pour toutes les composantes du système.
- *
- * @category AIT
- * @package AIT
- * @author Nicolas Thouvenin <nthouvenin@gmail.com>
- * @copyright 2009 Nicolas Thouvenin
- * @license http://opensource.org/licenses/lgpl-license.php LGPL
- * @link http://ait.touv.fr/
- */
- class AIT extends AITRoot
- {
- /**
- * @var boolean
- */
- static $debugging = false;
- /**
- * @var integer
- */
- static $time = 0;
- /**
- * @var integer
- */
- protected $_id;
- /**
- * @var string
- */
- protected $_element;
- /**
- * @var string
- */
- protected $_label;
- /**
- * @var integer
- */
- protected $_type;
- /**
- * @var array
- */
- protected $_methods = array();
- /**
- * @var array
- */
- protected $_cols = array(
- 'language' => 'string',
- 'scheme' => 'string',
- 'prefix' => 'string',
- 'suffix' => 'string',
- 'buffer' => 'string',
- 'dat_hash' => 'string',
- 'score' => 'integer',
- 'frequency' => 'integer',
- );
- /**
- * @var array
- */
- protected $_data = array();
- const VERSION = '2.0.0';
- const ORDER_ASC = 2;
- const ORDER_DESC = 4;
- const ORDER_BY_LABEL = 8;
- const ORDER_BY_SCORE = 16;
- const ORDER_BY_UPDATED = 32;
- const ORDER_BY_CREATED = 64;
- const ORDER_BY_FREQUENCY = 128;
- const ORDER_BY_RANK = 256;
- const INSERT_FIRST = 0;
- const ITEM = 1;
- const TAG = 2;
- // {{{ __construct
- /**
- * Constructeur
- *
- * @param PDOAIT $pdo objet de connexion à la base
- */
- function __construct(PDOAIT $pdo, $element)
- {
- $this->setPDO($pdo);
- $this->_element = $element;
- $cb = $this->getPDO()->getOption('callbacks');
- if (isset($cb[$element])) $this->setClassCallback($cb[$element]);
- }
- // }}}
- // {{{ catchError
- /**
- * Attrape toutes les erreurs de l'objet
- *
- * @param integer $m identifiant du tag
- * @param integer $i identifiant du tag
- *
- * @return boolean
- */
- public static function catchError(PDOException $e)
- {
- trigger_error($e->getMessage(), E_USER_ERROR);
- }
- // }}}
- // {{{ connect
- /**
- * Connection à la base
- *
- * @param string $dsn chaine de connexion
- * @param string $username user de connexion
- * @param string $password mot de passe de connexion
- * @param array $driver_options options pour pdo
- * @param array $ait_options options pour pdo
- *
- * @return PDO
- */
- public static function connect($dsn, $username = 'root', $password = '', array $driver_options = array(), array $ait_options = array())
- {
- try {
- $pdo = new PDOAIT($dsn, $username, $password, $driver_options);
- $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
- } catch (PDOException $e) {
- AIT::catchError($e);
- }
- $pdo->setOptions($ait_options);
- return $pdo;
- }
- // }}}
- // {{{ setClassCallback
- /**
- * Fixe des callback de class cad l'ajout de nouvelle méthode
- *
- * @access public
- */
- function setClassCallback(array $a)
- {
- foreach($a as $n => $c) {
- if (is_callable($c, true)) {
- $this->_methods[$n] = $c;
- }
- else {
- trigger_error($n.' passed to '.__METHOD__.' must be a valid callback', E_USER_ERROR);
- }
- }
- }
- // }}}
- // {{{ isClassCallback
- /**
- * Test si la callback est définie
- *
- * @access public
- */
- function isClassCallback($c)
- {
- if (isset($this->_methods[$c]))
- return true;
- else
- return false;
- }
- // }}}
- // {{{ callClassCallback
- /**
- * Lance une callback
- *
- * @param string name
- * @access public
- */
- function callClassCallback()
- {
- $c = func_get_arg(0);
- $r = func_get_args();
- array_shift($r);
- if ($this->isClassCallback($c)) {
- return call_user_func_array($this->_methods[$c], $r);
- }
- else
- return false;
- }
- // }}}
- // {{{ ren
- /**
- * Renomme l'élement courrant
- *
- * @param string $l nouveau label
- */
- function ren($l)
- {
- if ($l !== $this->_label) {
- $this->callClassCallback('renHook', $l, $this);
- $this->_label = $l;
- $this->_set('label', $this->_label);
- }
- }
- // }}}
- // {{{ exists
- /**
- * Verifie l'existence de l'élement courrant
- */
- function exists()
- {
- try {
- $sql = sprintf('
- SELECT count(*) FROM %s WHERE id=? LIMIT 0,1
- ',
- $this->getPDO()->tag()
- );
- $stmt = $this->getPDO()->prepare($sql);
- $stmt->bindParam(1, $this->_id, PDO::PARAM_INT);
- $stmt->execute();
- settype($this->_id, 'integer');
- $c = (int)$stmt->fetchColumn(0);
- $stmt->closeCursor();
- if ($c > 0) return true;
- else return false;
- }
- catch (PDOException $e) {
- self::catchError($e);
- }
- }
- // }}}
-
- // {{{ _checkTag
- /**
- * Vérifie l'existance et le type d'un tag
- * retourne false en cas de problème
- *
- * @param integer $i identifiant du tag
- * @param integer $t identifiant de son type
- *
- * @return boolean
- */
- protected function _checkTag($i, $t)
- {
- try {
- $sql = sprintf('
- SELECT count(*) n FROM %s WHERE id=? AND type=? LIMIT 0,1
- ',
- $this->getPDO()->tag()
- );
- $stmt = $this->getPDO()->prepare($sql);
- $stmt->bindParam(1, $i, PDO::PARAM_INT);
- $stmt->bindParam(2, $t, PDO::PARAM_INT);
- $stmt->execute();
- settype($i, 'integer');
- settype($t, 'integer');
- $c = (int)$stmt->fetchColumn(0);
- $stmt->closeCursor();
- if ($c > 0) return true;
- else return false;
- }
- catch (PDOException $e) {
- self::catchError($e);
- }
- }
- // }}}
- // {{{ _checkType
- /**
- * Vérifie l'existance d'un type d'un tag
- *
- * @param integer $t identifiant de son type
- *
- * @return boolean
- */
- protected function _checkType($t)
- {
- try {
- $sql = sprintf('
- SELECT count(*) FROM %s WHERE id=? LIMIT 0,1
- ',
- $this->getPDO()->tag()
- );
- $stmt = $this->getPDO()->prepare($sql);
- $stmt->bindParam(1, $t, PDO::PARAM_INT);
- $stmt->execute();
- $c = (int)$stmt->fetchColumn(0);
- $stmt->closeCursor();
- if ($c > 0) return true;
- else return false;
- }
- catch (PDOException $e) {
- self::catchError($e);
- }
- }
- // }}}
- // {{{ _checkTagged
- /**
- * Vérifie l'existance de l'association d'un tag et d'un item
- *
- * @param integer $m identifiant du tag
- * @param integer $i identifiant de l'item
- *
- * @return boolean
- */
- protected function _checkTagged($m, $i)
- {
- try {
- $sql = sprintf('
- SELECT count(*) n FROM %s WHERE tag_id=? and item_id=? LIMIT 0,1
- ',
- $this->getPDO()->tagged()
- );
- $stmt = $this->getPDO()->prepare($sql);
- $stmt->bindParam(1, $m, PDO::PARAM_INT);
- $stmt->bindParam(2, $i, PDO::PARAM_INT);
- $stmt->execute();
- settype($m, 'integer');
- settype($i, 'integer');
- $c = (int)$stmt->fetchColumn(0);
- $stmt->closeCursor();
- if ($c > 0) return true;
- else return false;
- }
- catch (PDOException $e) {
- self::catchError($e);
- }
- }
- // }}}
- // {{{ _increaseFrequency
- /**
- * Incremente la frequence d'une ligne dans TAG
- *
- * @param string $t id
- */
- protected function _increaseFrequency($i)
- {
- try {
- $sql = sprintf('
- SELECT frequency FROM %s WHERE id = ? LIMIT 0,1
- ',
- $this->getPDO()->tag()
- );
- self::timer();
- $stmt = $this->getPDO()->prepare($sql);
- $stmt->bindParam(1, $i, PDO::PARAM_INT);
- $stmt->execute();
- settype($i, 'integer');
- $f = (int) $stmt->fetchColumn(0);
- $stmt->closeCursor();
- self::debug(self::timer(true), $sql, $i);
- ++$f;
- if ($f <= 0) $f = 1; // Control IMPORTANT
- $sql = sprintf('
- UPDATE %s SET frequency = ? WHERE id = ?
- ',
- $this->getPDO()->tag(true)
- );
- self::timer();
- $stmt = $this->getPDO()->prepare($sql);
- $stmt->bindParam(1, $f, PDO::PARAM_INT);
- $stmt->bindParam(2, $i, PDO::PARAM_INT);
- $stmt->execute();
- settype($f, 'integer');
- settype($i, 'integer');
- $stmt->closeCursor();
- self::debug(self::timer(true), $sql, $f, $i);
- }
- catch (PDOException $e) {
- self::catchError($e);
- }
- }
- // }}}
- // {{{ _decreaseFrequency
- /**
- * Incremente la frequence d'une ligne dans TAG
- *
- * @param string $t id
- */
- protected function _decreaseFrequency($i)
- {
- try {
- $sql = sprintf('
- SELECT frequency FROM %s WHERE id = ? LIMIT 0,1
- ',
- $this->getPDO()->tag()
- );
- self::timer();
- $stmt = $this->getPDO()->prepare($sql);
- $stmt->bindParam(1, $i, PDO::PARAM_INT);
- $stmt->execute();
- settype($i, 'integer');
- $f = (int) $stmt->fetchColumn(0);
- $stmt->closeCursor();
- self::debug(self::timer(true), $sql, $i);
- --$f;
- if ($f <= 0) $f = 0; // Control IMPORTANT
- $sql = sprintf('
- UPDATE %s SET frequency = ? WHERE id = ?
- ',
- $this->getPDO()->tag(true)
- );
- self::timer();
- $stmt = $this->getPDO()->prepare($sql);
- $stmt->bindParam(1, $f, PDO::PARAM_INT);
- $stmt->bindParam(2, $i, PDO::PARAM_INT);
- $stmt->execute();
- settype($f, 'integer');
- settype($i, 'integer');
- $stmt->closeCursor();
- self::debug(self::timer(true), $sql, $f, $i);
- }
- catch (PDOException $e) {
- self::catchError($e);
- }
- }
- // }}}
- // {{{ _addTagged
- /**
- * Ajout d'une ligne dans la table tagged
- *
- * @param string $t tag id
- * @param string $i item id
- * @param in $p position
- */
- protected function _addTagged($t, $i, $p = null)
- {
- try {
- if (is_null($p) or $p === 0) {
- $sql = sprintf('
- INSERT INTO %1$s (tag_id, item_id, rank) SELECT ?, ?, %2$s FROM %1$s WHERE item_id = ? LIMIT 0,1
- ',
- $this->getPDO()->tagged(true),
- ($p === 0 ? 'min(rank) - 1' : 'max(rank) + 1')
- );
- self::timer();
- $stmt = $this->getPDO()->prepare($sql);
- $stmt->bindParam(1, $t, PDO::PARAM_INT);
- $stmt->bindParam(2, $i, PDO::PARAM_INT);
- $stmt->bindParam(3, $i, PDO::PARAM_INT);
- $stmt->execute();
- settype($t, 'integer');
- settype($i, 'integer');
- $stmt->closeCursor();
- self::debug(self::timer(true), $sql, $t, $i, $i);
- }
- else {
- $sql = sprintf('
- SELECT rank
- FROM %s
- WHERE tag_id = ? and item_id = ?
- ',
- $this->getPDO()->tagged(true)
- );
- self::timer();
- $stmt = $this->getPDO()->prepare($sql);
- $stmt->bindParam(1, $p, PDO::PARAM_INT);
- $stmt->bindParam(2, $i, PDO::PARAM_INT);
- $stmt->execute();
- $rank = (int) $stmt->fetchColumn(0);
- settype($p, 'integer');
- settype($i, 'integer');
- $stmt->closeCursor();
- self::debug(self::timer(true), $sql, $p, $i);
- $sql = '
- SET @rank = ?;
- ';
- self::timer();
- $stmt = $this->getPDO()->prepare($sql);
- $stmt->bindParam(1, $rank, PDO::PARAM_INT);
- $stmt->execute();
- settype($rank, 'integer');
- settype($i, 'integer');
- $stmt->closeCursor();
- self::debug(self::timer(true), $sql, $rank);
- $sql = sprintf('
- UPDATE %s SET rank = (SELECT @rank := @rank + 1) WHERE item_id = ? ORDER BY rank;
- ',
- $this->getPDO()->tagged(true)
- );
- self::timer();
- $stmt = $this->getPDO()->prepare($sql);
- $stmt->bindParam(1, $i, PDO::PARAM_INT);
- $stmt->execute();
- settype($rank, 'integer');
- settype($i, 'integer');
- $stmt->closeCursor();
- self::debug(self::timer(true), $sql, $i);
- ++$rank;
- $sql = sprintf('
- INSERT INTO %s (tag_id, item_id, rank) VALUES (?, ?, ?);
- ',
- $this->getPDO()->tagged(true)
- );
- self::timer();
- $stmt = $this->getPDO()->prepare($sql);
- $stmt->bindParam(1, $t, PDO::PARAM_INT);
- $stmt->bindParam(2, $i, PDO::PARAM_INT);
- $stmt->bindParam(3, $rank, PDO::PARAM_INT);
- $stmt->execute();
- settype($t, 'integer');
- settype($i, 'integer');
- settype($rank, 'integer');
- $stmt->closeCursor();
- self::debug(self::timer(true), $sql, $t, $i, $rank);
- }
- }
- catch (PDOException $e) {
- self::catchError($e);
- }
- }
- // }}}
- // {{{ _rmTagged
- /**
- * Supprime une ligne dans la table tagged
- *
- * @param string $t tag id
- * @param string $i item id
- */
- protected function _rmTagged($t, $i)
- {
- try {
- if (is_null($t) and !is_null($i)) {
- $field = 'item_id';
- $value = $i;
- }
- elseif (!is_null($t) and is_null($i)) {
- $field = 'tag_id';
- $value = $t;
- }
- else
- throw new Exception('Bad Arguments');
- $sql = sprintf('
- DELETE FROM %s WHERE %s=?
- ',
- $this->getPDO()->tagged(true),
- $field
- );
- self::timer();
- $stmt = $this->getPDO()->prepare($sql);
- $stmt->bindParam(1, $value, PDO::PARAM_INT);
- $stmt->execute();
- $stmt->closeCursor();
- self::debug(self::timer(true), $sql, $this->_id);
- }
- catch (PDOException $e) {
- self::catchError($e);
- }
- }
- // }}}
- // {{{ _rmTag
- /**
- * Suppression d'une ligne dans tag
- *
- */
- protected function _rmTag()
- {
- $dat_hash = $this->_get('dat_hash', true);
- try {
- $sql = sprintf('
- DELETE FROM %s WHERE id=?
- ',
- $this->getPDO()->tag(true)
- );
- self::timer();
- $stmt = $this->getPDO()->prepare($sql);
- $stmt->bindParam(1, $this->_id, PDO::PARAM_INT);
- $stmt->execute();
- settype($this->_id, 'integer');
- $stmt->closeCursor();
- self::debug(self::timer(true), $sql, $this->_id);
- $this->_id = null;
- $sql = sprintf('
- DELETE FROM %2$s
- USING %2$s
- LEFT JOIN %1$s tag ON %2$s.hash=tag.dat_hash
- WHERE hash=? AND tag.id is NULL
- ',
- $this->getPDO()->tag(true),
- $this->getPDO()->dat(true)
- );
- self::timer();
- $stmt = $this->getPDO()->prepare($sql);
- $stmt->bindParam(1, $dat_hash, PDO::PARAM_STR);
- $stmt->execute();
- $stmt->closeCursor();
- self::debug(self::timer(true), $sql, $dat_hash);
- }
- catch (PDOException $e) {
- self::catchError($e);
- }
- }
- // }}}
- // {{{ _addTag
- /**
- * Ajout d'une ligne dans la table tag
- *
- * @param string $l label
- * @param string $t type
- * @param array $r champ associé
- *
- * @return integer
- */
- protected function _addTag($l, $t = null, $r = false)
- {
- try {
- $sql = sprintf('
- SELECT id FROM %s WHERE label=? and type=? LIMIT 0,1
- ',
- $this->getPDO()->tag()
- );
- $stmt = $this->getPDO()->prepare($sql);
- $stmt->bindParam(1, $l, PDO::PARAM_STR);
- $stmt->bindParam(2, $t, PDO::PARAM_INT);
- $stmt->execute();
- settype($t, 'integer');
- $id = $stmt->fetchColumn();
- $stmt->closeCursor();
- if ($id !== false) return (int) $id;
- if (isset($r['content'])) {
- $r['dat_hash'] = sha1($r['content'], true);
- self::timer();
- $sql = sprintf('
- INSERT IGNORE INTO %s (hash, content) VALUES (?, ?);
- ',
- $this->getPDO()->dat(true)
- );
- $stmt = $this->getPDO()->prepare($sql);
- $stmt->bindParam(1, $r['dat_hash'], PDO::PARAM_STR);
- $stmt->bindParam(2, $r['content'], PDO::PARAM_STR);
- $ret = $stmt->execute();
- $stmt->closeCursor();
- self::debug(self::timer(true), $sql, $r['dat_hash'], $r['content']);
- }
- $sqlA = $sqlB = '';
- $fields = array();
- foreach($this->_cols as $name => $typage) {
- if (isset($r[$name])) {
- settype($r[$name], $typage);
- $fields[] = $this->_data[$name] = $r[$name];
- $sqlA .= ','.$name;
- $sqlB .= ',?';
- }
- }
- self::timer();
- if (is_null($t)) {
- $sql = sprintf('
- INSERT INTO %s (label, updated, created %s) VALUES (?, now(), now() %s);
- ',
- $this->getPDO()->tag(true),
- $sqlA,
- $sqlB
- );
- $stmt = $this->getPDO()->prepare($sql);
- $stmt->bindParam(1, $l, PDO::PARAM_STR);
- $n = 2;
- }
- else {
- $sql = sprintf('
- INSERT INTO %s (label, type, updated, created %s) VALUES (?, ?, now(), now() %s);
- ',
- $this->getPDO()->tag(true),
- $sqlA,
- $sqlB
- );
- $stmt = $this->getPDO()->prepare($sql);
- $stmt->bindParam(1, $l, PDO::PARAM_STR);
- $stmt->bindParam(2, $t, PDO::PARAM_INT);
- $n = 3;
- }
- foreach($fields as $k => $field) {
- $typage = gettype($field);
- if ($typage === 'integer')
- $stmt->bindParam($k + $n, $field, PDO::PARAM_INT);
- elseif ($typage === 'string')
- $stmt->bindParam($k + $n, $field, PDO::PARAM_STR);
- }
- $ret = $stmt->execute();
- $stmt->closeCursor();
- self::debug(self::timer(true), $sql, $l, $t, $r);
- $id = (int) $this->getPDO()->lastInsertId();
- }
- catch (PDOException $e) {
- self::catchError($e);
- }
- return $id;
- }
- // }}}
- // {{{ _getTagBySystemID
- /**
- * Retroune une ligne dans la table tag à partir de l'identifiant physique
- *
- * @param integer $i
- *
- * @return array
- */
- protected function _getTagBySystemID($i)
- {
- $sql = sprintf('
- SELECT id, label, prefix, suffix, buffer, scheme, dat_hash, language, score, frequency, type, content
- FROM %s tag
- LEFT JOIN %s dat ON tag.dat_hash=dat.hash
- WHERE id = ?
- LIMIT 0,1
- ',
- $this->getPDO()->tag(),
- $this->getPDO()->dat()
- );
- self::timer();
- if (($r = $this->callClassCallback(
- 'getTagBySystemIDCache',
- $cid = self::str2cid($sql, $i)
- )) !== false) return $r;
- try {
- $stmt = $this->getPDO()->prepare($sql);
- $stmt->bindParam(1, $i, PDO::PARAM_INT);
- $stmt->execute();
- $row = $stmt->fetch(PDO::FETCH_ASSOC);
- $stmt->closeCursor();
- }
- catch (PDOException $e) {
- self::catchError($e);
- }
- self::debug(self::timer(true), $sql, $i);
- if (is_array($row)) {
- settype($row['type'], 'integer');
- settype($row['id'], 'integer');
- }
- if (isset($cid))
- $this->callClassCallback('getTagBySystemIDCache', $cid, $row);
- return $row;
- }
- // }}}
- // {{{ _set
- /**
- * Méthode permettant de changer la valeur d'une colonne
- *
- * @param string $name nom de la colonne
- * @param mixed $value valeur de la colonne
- */
- protected function _set($n, $v)
- {
- $this->callClassCallback('setHook', $n, $v, $this);
- $this->_data[$n] = $v;
- if ($n === 'content') {
- $dat_hash = sha1($r['content'], true);
- $this->_set('dat_hash', $dat_hash);
- self::timer();
- $sql = sprintf('
- INSERT IGNORE INTO %s (hash, content) VALUES (?, ?);
- ',
- $this->getPDO()->dat(true)
- );
- $stmt = $this->getPDO()->prepare($sql);
- $stmt->bindParam(1, $dat_hash, PDO::PARAM_STR);
- $stmt->bindParam(2, $v, PDO::PARAM_STR);
- $ret = $stmt->execute();
- $stmt->closeCursor();
- self::debug(self::timer(true), $sql, $dat_hash, $v);
- }
- try {
- self::timer();
- $sql = sprintf('
- UPDATE %s set %s=? WHERE id=?
- ',
- $this->getPDO()->tag(true), $n
- );
- $stmt = $this->getPDO()->prepare($sql);
- $typ = gettype($v);
- if ($typ === 'string')
- $stmt->bindParam(1, $v, PDO::PARAM_STR);
- elseif ($typ === 'integer')
- $stmt->bindParam(1, $v, PDO::PARAM_INT);
- else
- throw new Exception('type not supported (`'.$typ.'`)');
- $stmt->bindParam(2, $this->_id, PDO::PARAM_INT);
- $stmt->execute();
- settype($this->_id, 'integer');
- $stmt->closeCursor();
- self::debug(self::timer(true), $sql, $v, $this->_id);
- }
- catch (PDOException $e) {
- self::catchError($e);
- }
- }
- // }}}
- // {{{ _fill
- /**
- * Méthode permettant de charger les propritétes de l'objet
- * à partir d'un tableau de données
- *
- * @param array $a
- */
- protected function _fill($a)
- {
- if (is_array($a)) {
- foreach($this->_cols as $n => $t) {
- if (isset($a[$n])) {
- $this->_data[$n] = $a[$n];
- settype($this->_data[$n], $t);
- }
- }
- if (isset($a['content'])) {
- $this->_data['content'] = $a['content'];
- }
- }
- }
- // }}}
- //
- // {{{ filter
- /**
- * Création de filtre sql sur les colonnes complétaires
- *
- * @param array $a
- * @param strinf $c
- */
- protected function filter($a, $c = 'tag')
- {
- $sql = '';
- if (is_array($a))
- foreach($this->_cols as $n => $t)
- if (isset($a[$n]))
- $sql = ' AND '.$c.'.'.$n.'='.$this->getPDO()->quote($a[$n], $t === 'integer' ? PDO::PARAM_INT : PDO::PARAM_STR);
- return $sql;
- }
- // }}}
- // {{{ _get
- /**
- * Méthode permettant d'accéder à la valeur d'une colonne
- *
- * @param string $n nom de la colonne
- * @param boolean $reload récupére la valeur en base et non celle du cache de l'objet
- *
- * @return mixed
- */
- protected function _get($n, $reload = false)
- {
- if ($reload === true && isset($this->_data[$n])) unset($this->_data[$n]);
- if (!isset($this->_data[$n])) {
- try {
- self::timer();
- $sql = sprintf('
- SELECT id, label, prefix, suffix, buffer, scheme, dat_hash, language, score, frequency, type, content
- FROM %s tag
- LEFT JOIN %s dat ON tag.dat_hash=dat.hash
- WHERE id = ?
- LIMIT 0,1
- ',
- $this->getPDO()->tag(),
- $this->getPDO()->dat()
- );
- $stmt = $this->getPDO()->prepare($sql);
- $stmt->bindParam(1, $this->_id, PDO::PARAM_INT);
- $stmt->execute();
- settype($this->_id, 'integer');
- $a = $stmt->fetch(PDO::FETCH_ASSOC);
- $this->_fill($a);
- $stmt->closeCursor();
- self::debug(self::timer(true), $sql, $this->_id);
- }
- catch (PDOException $e) {
- self::catchError($e);
- }
- }
- return isset($this->_data[$n]) ? $this->_data[$n] : null;
- }
- // }}}
- // {{{ getSystemID
- /**
- * getSystemID
- *
- * @return integer
- */
- public function getSystemID()
- {
- return $this->_id;
- }
- // }}}
- // {{{ get
- /**
- * Getter
- *
- * @param string $name nom de l'attribut
- *
- * @return mixed
- */
- public function get($name = 'label')
- {
- $attr = array(
- 'internal_id' => 'id',
- 'type' => 'type',
- 'label' => 'label',
- 'value' => 'label',
- );
- if (isset($attr[$name])) {
- $name = '_'.$attr[$name];
- $value = $this->$name;
- }
- if (isset($this->_cols[$name]) or $name === 'content') {
- $value = $this->_get($name);
- }
- if ($this->isClassCallback('getHook')) {
- $value = $this->callClassCallback('getHook', $name, $value, $this);
- }
- return $value;
- }
- // }}}
- // {{{ set
- /**
- * Setter
- *
- * @param string $value
- * @param string $name nom de l'attribut
- *
- * @return mixed
- */
- public function set($value, $name = 'label')
- {
- if ($name === 'label') {
- return $this->ren($value);
- }
- elseif (isset($this->_cols[$name])) {
- return $this->_set($name, $value);
- }
- }
- // }}}
- // {{{ getTimestamps
- /**
- * getTimestamps
- *
- * @return ArrayObject
- */
- public function getTimestamps()
- {
- try {
- $sql = sprintf('
- SELECT UNIX_TIMESTAMP(updated), UNIX_TIMESTAMP(created) FROM %s WHERE id=? LIMIT 0,1
- ',
- $this->getPDO()->tag()
- );
- $stmt = $this->getPDO()->prepare($sql);
- $stmt->bindParam(1, $this->_id, PDO::PARAM_INT);
- $stmt->execute();
- settype($this->_id, 'integer');
- $ret = $stmt->fetch();
- $stmt->closeCursor();
- return new ArrayObject(
- array(
- 'updated' => (int) $ret[0],
- 'created' => (int) $ret[1],
- ), ArrayObject::ARRAY_AS_PROPS
- );
- }
- catch (PDOException $e) {
- self::catchError($e);
- }
- }
- // }}}
- // {{{ getScore
- /**
- * Revoit le score de l'élement
- *
- * @return integer
- */
- public function getScore()
- {
- return (int) $this->_get('score');
- }
- // }}}
- // {{{ setScore
- /**
- * Revoit le score de l'élement
- *
- * @param integer $i
- */
- public function setScore($i)
- {
- if (!is_int($i))
- trigger_error('Argument 1 passed to '.__METHOD__.' must be a integer, '.gettype($i).' given', E_USER_ERROR);
- $this->_set('score', $i);
- }
- // }}}
- // {{{ setScore
- /**
- * Renvoit la frequence de l'élement
- *
- * @param integer $i
- */
- public function setFrequency($i)
- {
- if (!is_int($i))
- trigger_error('Argument 1 passed to '.__METHOD__.' must be a integer, '.gettype($i).' given', E_USER_ERROR);
- $this->_set('frequency', $i);
- }
- // }}}
- // {{{ search
- /**
- * Recherche un objet quelque soit sont type
- *
- * @param string $query requete (le format dépend de la search_callback) sans callback c'est du SQL
- * @param integer $offset décalage à parir du premier enregistrement
- * @param integer $lines nombre de lignes à retourner
- * @param integer $ordering flag permettant le tri
- *
- * @return AITResult
- */
- public function search($query, $offset = null, $lines = null, $ordering = null)
- {
- if (!is_null($offset) && !is_int($offset))
- trigger_error('Argument 3 passed to '.__METHOD__.' must be a integer, '.gettype($offset).' given', E_USER_ERROR);
- if (!is_null($lines) && !is_int($lines))
- trigger_error('Argument 4 passed to '.__METHOD__.' must be a integer, '.gettype($lines).' given', E_USER_ERROR);
- if (!is_null($ordering) && !is_int($ordering))
- trigger_error('Argument 5 passed to '.__METHOD__.' must be a integer, '.gettype($ordering).' given', E_USER_ERROR);
- if ($this->isClassCallback('searchHook'))
- $query = $this->callClassCallback('searchHook', $query, $this);
- if ($query !== '' and $query !== false) $query = 'AND '.$query;
- $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';
- $sql2 = sprintf('
- FROM %1$s tag
- LEFT JOIN %1$s b ON tag.type=b.id
- WHERE tag.type != 0 %2$s
- ',
- $this->getPDO()->tag(),
- $query
- );
- $sql = $sql1.$sql2;
- self::sqler($sql, $offset, $lines, $ordering);
- self::timer();
- $stmt = $this->getPDO()->prepare($sql);
- $stmt->execute();
- $ret = array();
- while (($row = $stmt->fetch(PDO::FETCH_ASSOC))) {
- if (is_null($row['id'])) continue;
- $ret[] = self::factory($this->getPDO(), $row);
- }
- $stmt->closeCursor();
- self::debug(self::timer(true), $sql, $this->_id, $this->_id);
- $sql = 'SELECT COUNT(*) '.$sql2;
- $r = new AITResult($ret);
- $r->setQueryForTotal($sql, array($this->_id => PDO::PARAM_INT,), $this->getPDO());
- return $r;
- }
- // }}}
- // {{{ factory
- /**
- * Créer un objet à partir d'un tableau de donnée
- *
- * @param PDOAIT $pdo pointeur sur la base de données
- * @param array $row
- *
- * @return mixed
- */
- public static function factory(PDOAIT $pdo, $row)
- {
- if (!is_array($row))
- trigger_error('Argument 2 passed to '.__METHOD__.' must be a array, '.gettype($row).' given', E_USER_ERROR);
- if (!isset($row['type']) or !isset($row['id']) or !isset($row['crtl']) or !isset($row['label']))
- trigger_error('Argument 2 passed to '.__METHOD__.' has one or more keys missing (id, label, type, crtl)', E_USER_ERROR);
- settype($row['type'], 'integer');
- settype($row['id'], 'integer');
- settype($row['crtl'], 'integer');
- $o = null;
- if ($row['type'] === self::ITEM) {
- $o = new AIT_ItemType($row['label'], $pdo, $row['id'], $row);
- }
- elseif ($row['type'] === self::TAG) {
- $o = new AIT_TagType($row['label'], null, $pdo, $row['id'], $row);
- }
- elseif ($row['crtl'] === self::ITEM) {
- $o = new AIT_Item($row['label'], $row['type'], $pdo, $row['id'], $row);
- }
- elseif ($row['crtl'] === self::TAG) {
- $o = new AIT_Tag($row['label'], $row['type'], null, $pdo, $row['id'], $row);
- }
- return $o;
- }
- // }}}
- // {{{ getBySystemID
- /**
- * Récupère…
Large files files are truncated, but you can click here to view the full file