123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005 |
- <?php
- /**
- * Classe de gestion ORM
- * @author mathieu
- * @package db_object
- *
- */
- class db_object_manager
- {
- /**
- * Liste des types de champ "simples" (dans la table principale en base de donnée)
- * @var []
- */
- public $field_simple = array("int", "float", "string", "password", "text", "richtext", "object", "timestamp", "bool", 'date', "select", "select_multiple", "file", "img");
- /**
- * Debug database operations
- * @var bool
- */
- public $DB_DEBUG = false;
- /**
- * Debug file operations
- * @var bool
- */
- public $FILE_DEBUG = false;
- /**
- * Class name
- * @var string
- */
- public $_name = "";
- public $_label = "";
- /**
- * Database name
- * @var string
- */
- public $_db_table = "";
- /**
- * ID field name in database
- * @var string
- */
- public $_db_id = "id";
- /**
- * Fields specifications
- * @var []
- */
- public $_fields = array();
- /**
- * More fields specifications
- * @var []
- */
- public $_fields_more = array();
- public $_db_fields_more_table = '';
- /**
- * Fields to display in lists
- * @var []
- */
- public $_field_disp_list = array();
- /**
- * Object list cache
- * @var []
- */
- private $list = array();
- /**
- * Object list cache
- * @var []
- */
- private $list_ref = array();
- /**
- * Constructeur
- */
- public function __construct()
- {
- if (!$this->_name)
- $this->_name = substr(get_class($this), 0, -8);
- if (!$this->_db_table)
- $this->_db_table = $this->_name;
- }
- /**
- * Returns if an object exists
- * @param int $id
- * @return bool
- */
- public function exists($id)
- {
- if (!is_numeric($id))
- {
- return false;
- }
- elseif (isset($this->list[$id]))
- {
- return true;
- }
- elseif ($object=$this->get($id))
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- /**
- * Returns if an object exists
- * @param name $string
- * @return bool
- */
- public function exists_ref($ref)
- {
- if (!isset($this->_fields['ref']))
- {
- return false;
- }
- elseif (!is_string($ref))
- {
- return false;
- }
- elseif (isset($this->list_ref[$ref]))
- {
- return true;
- }
- elseif ($object=$this->get_ref($ref))
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- /**
- * Renvoie un object de la base
- * @param string $ref
- * @return db_object
- */
- public function get_ref($ref)
- {
- if (!isset($this->_fields['ref']))
- {
- return false;
- }
- elseif (!is_string($ref))
- {
- return false;
- }
- elseif (isset($this->list_ref[$ref]))
- {
- return $this->list[$this->list_ref[$ref]];
- }
- elseif (count($objects=$this->select("ref='".mysql_real_escape_string($ref)."'"))==1)
- {
- return array_pop($objects);
- }
- else
- {
- return false;
- }
- }
- /**
- * Renvoie un object de la base
- * @param int $id
- * @return db_object
- */
- public function get($id)
- {
- if (!is_numeric($id))
- {
- return false;
- }
- elseif (isset($this->list[$id]))
- {
- return $this->list[$id];
- }
- elseif(count($objects=$this->select('id='.$id))==1)
- {
- return array_pop($objects);
- }
- else{
- return false;
- }
- }
- /**
- * Select en base de donnée
- * @param [] $params
- * @param int $limit
- * @param string $order
- * @return []
- */
- public function select($params=null, $limit=null, $order=null)
- {
- $classname = $this->_name;
- $list = array();
- foreach ($this->db_retrieve($params, $limit, $order) as $row)
- {
- if (!isset($this->list[$row["id"]])){
- $this->list[$row["id"]] = $object = new $classname(null, $row);
- if (isset($row['ref']))
- $this->list_ref[$row["ref"]] = $row["id"];
- }
- else
- $object = $this->list[$row["id"]];
- $list[] = $object;
- }
- return $list;
- }
- /**
- * Select en base de donnée
- * @param [] $params
- * @param int $limit
- * @param string $order
- * @return []
- */
- public function db_retrieve($params=null, $limit=null, $order=null)
- {
- if ($params)
- $q_where = "WHERE ".$params;
- else
- $q_where = "";
- if ($limit)
- $q_limit = "LIMIT ".$limit;
- else
- $q_limit = "";
- if ($order){
- $q_o = array();
- foreach(explode(', ', $order) as $o)
- if (count($o2=explode(' ', trim($o)))>1)
- $q_o[] = "`".$o2[0]."` ".$o2[1];
- else
- $q_o[] = "`".$o2[0]."`";
- $q_order = "ORDER BY ".implode(', ', $q_o);
- }
- else
- $q_order = "";
- $select_more = array();
- $type_select_multiple = array();
- $q_select = array("`".$this->_db_id."` as `id`");
- foreach($this->_fields as $name=>$field)
- {
- if (in_array($field["type"], $this->field_simple))
- {
- if ($field["type"] == "select_multiple")
- $type_select_multiple[] = $name;
- if (isset($field["db_fieldname"]))
- $q_select[] = "`".$field["db_fieldname"]."` as `".$name."`";
- else
- $q_select[] = "`".$name."`";
- }
- elseif ($field["type"] == "object_list")
- {
- $select_more[] = $name;
- }
- }
- $q_s = "SELECT ".implode(", ", $q_select)." FROM `".$this->_db_table."` ".$q_where." ".$q_order." ".$q_limit;
- $q_r = mysql_query($q_s);
- if ($this->DB_DEBUG == true || ($error=mysql_error()))
- {
- echo "$q_s : ".$error;
- }
- $list = array();
- $list_id = array();
- while ($row=mysql_fetch_assoc($q_r))
- {
- // @todo : tout pourris...
- foreach($row as $i=>$j)
- $row[$i] = stripslashes($j);
- foreach($type_select_multiple as $name)
- {
- if ($row[$name] !== null)
- $row[$name] = explode(",", $row[$name]);
- else
- $row[$name] = array();
- }
- $list[$row["id"]] = $row;
- $list_id[] = $row["id"];
- }
- // Fields of type : object_list
- foreach($select_more as $name)
- {
- $field = $this->_fields[$name];
- $classname = $field["object_type"];
- $q_s = "SELECT `".$field["db_field_id"]."` as id, `".$field["db_field_ref_id"]."` as ref_id FROM `".$field["db_table"]."` WHERE `".$field["db_field_ref_id"]."` IN (".implode(", ", $list_id).")";
- $q_r = mysql_query($q_s);
- while ($row=mysql_fetch_assoc($q_r))
- {
- $list[$row["ref_id"]][$name][] = $row["id"];
- }
- }
- // More fields
- foreach($this->db_retrieve_more($list_id) as $id=>$row)
- $list[$id] = array_merge($list[$id], $row);
- return $list;
- }
- /**
- * retrieve more info
- * @param []int $list_id
- */
- protected function db_retrieve_more($list_id=null)
- {
- return array();
- }
- /**
- * Count en base de donnée
- * @param [] $params
- * @return int
- */
- public function count($params=null)
- {
- $classname = $this->_name;
- if ($params)
- $q_where = "WHERE ".$params;
- else
- $q_where = "";
- $q_s = "SELECT COUNT(*) FROM `".$this->_db_table."` ".$q_where;
- $q_r = mysql_query($q_s);
- if ($this->DB_DEBUG == true)
- {
- echo "$q_s : ".mysql_error();
- }
- $row = mysql_fetch_row($q_r);
- return array_pop($row);
- }
- }
- /**
- * Classe objet ORM
- * @author mathieu
- * @package db_object
- *
- */
- class db_object
- {
- /**
- * Class name
- * @var string
- */
- public $_name = "";
- /**
- * Manager object
- * @access public
- * @var db_object_manager
- */
- public $_manager = null;
- /**
- * Object ID
- * @var int
- */
- public $id = null;
- /* CONSTRUCT */
- /**
- * Constructeur
- * @param int $id
- * @param [] $info
- */
- public function __construct($id=null, $info=null)
- {
- if (!$this->_name)
- $this->_name = get_class($this);
- $classname = $this->_name;
- $this->_manager = $classname();
- foreach ($this->_manager->_fields as $name=>$value)
- $this->$name = null;
- if (is_numeric($id))
- {
- if ($info=$this->db_retrieve($id))
- $this->field_update($info);
- }
- elseif (is_array($info))
- {
- $this->field_update($info);
- }
- }
- /* DISPLAY */
- /**
- * Default display
- * @return string
- */
- public function __tostring()
- {
- if ($this->id)
- return $this->_manager->_name." #".$this->id;
- else
- return $this->_manager->_name." # en cours...";
- }
- /**
- * Return image url
- * @param string $name
- * @return string
- */
- public function file($name)
- {
- if (isset($this->_manager->_fields[$name]) && in_array($this->_manager->_fields[$name]["type"], array("img", "file")) && $this->$name)
- {
- return $this->_manager->_fields[$name]["folder"]."/".$this->$name;
- }
- }
- /**
- * Return object associated to a field
- * @param string $fieldname
- * @return db_object
- */
- function object($fieldname)
- {
- if (!is_string($fieldname) || !isset($this->_manager->_fields[$fieldname]))
- return;
- $field = $this->_manager->_fields[$fieldname];
- if (!isset($field["type"]) || $field["type"] != "object" || !isset($field["object_type"]))
- return;
- if (!is_string($classname=$field["object_type"]) || !class_exists($classname))
- return;
- if (!is_numeric($this->$fieldname))
- return;
- return $classname()->get($this->$fieldname);
- }
- /* INSERT UPDATE VERIF */
- public function field_calculated(&$info)
- {
- foreach($this->_manager->_fields as $name=>&$field) if (isset($field['calculate'])){
- list($type, $var) = explode(':', $field['calculate']);
- if ($type=='url'){
- if (!isset($info[$var]))
- continue;
- $url = strtolower(stripAccents($info[$var]));
- $patterns = $replacements = array();
- $patterns[0] = '/(&|&)/i';
- $replacements[0] = '-and-';
- $patterns[1] = '/[^a-zA-Z01-9]/i';
- $replacements[1] = '-';
- $patterns[2] = '/(-+)/i';
- $replacements[2] = '-';
- $patterns[3] = '/(-$|^-)/i';
- $replacements[3] = '';
- $url = preg_replace($patterns, $replacements, $url);
- if (strlen($url)>100){
- $urle = explode('-', $url);
- while (strlen($url)>100){
- array_pop($urle);
- $url = implode('-', $urle);
- }
- }
- $info[$name] = $url;
- }
- if ($type=='ref'){
- if (!isset($info[$var]))
- continue;
- $url = strtolower(stripAccents($info[$var]));
- $patterns = $replacements = array();
- $patterns[0] = '/(&|&)/i';
- $replacements[0] = '';
- $patterns[1] = '/[^a-zA-Z01-9]/i';
- $replacements[1] = '_';
- $patterns[2] = '/(_+)/i';
- $replacements[2] = '_';
- $patterns[3] = '/(_$|^_)/i';
- $replacements[3] = '';
- $url = preg_replace($patterns, $replacements, $url);
- $urle = explode('_', $url);
- $s = 0;
- while (strlen($url)>20) {
- $s++;
- foreach($urle as $i=>&$j) {
- if (strlen($j)<=$s) {
- unset($urle[$i]);
- $url = implode('_', $urle);
- if (strlen($url)<=20)
- break;
- }
- }
- }
- while (strlen($url)>50){
- array_pop($urle);
- $url = implode('_', $urle);
- }
- $info[$name] = $url;
- }
- }
- //var_dump($info); die();
- }
- /**
- * Contrôle des champs
- * @param [] $info
- */
- public function field_verif(&$info)
- {
- if (!is_array($info))
- $info = array();
- foreach($info as $name=>&$value)
- {
- if (!isset($this->_manager->_fields[$name]))
- {
- unset($info[$name]);
- }
- else
- {
- $field = $this->_manager->_fields[$name];
- if (isset($field["type"]))
- {
- $type = $field["type"];
- if (in_array($type, array("object", "int", "float", "numeric", "decimal")) && !is_numeric($value))
- {
- $value = NULL;
- }
- elseif ($type == "boolean")
- {
- $value = ($value) ?1 :0;
- }
- elseif ($type == "object" && $value)
- {
- $object_classname = $field["object_type"];
- if (!$object_classname()->exists($value))
- $value = NULL;
- }
- elseif (in_array($type, array("string", "text", "richtext")) && !is_string($value))
- {
- $value = NULL;
- }
- elseif ($type == "select" && ((!is_string($value) && !is_numeric($value)) || !isset($field["list"][$value])))
- {
- $value = NULL;
- }
- elseif ($type == "select_multiple")
- {
- if (!is_array($value))
- {
- $value = NULL;
- }
- else
- {
- foreach($value as $i=>$v)
- if (!isset($field["list"][$v]))
- unset($value[$i]);
- }
- }
- elseif ($type == "date" && (!is_string($value)))
- {
- $value = NULL;
- }
- elseif (in_array($type, array("datetime", "timestamp")) && (!is_string($value)))
- {
- $value = NULL;
- }
- elseif ($type == "img" || $type == "file")
- {
- //var_dump($_FILES);
- // Sans upload ou upload foireux
- if (isset($_FILES[$name]) && (!$_FILES[$name]["tmp_name"] || $_FILES[$name]["error"] != UPLOAD_ERR_OK))
- {
- unset($_FILES[$name]);
- }
- // Fichier sans nom ou nom foireux
- if (isset($_FILES[$name]))
- {
- if (isset($field["filename"]))
- {
- $_FILES[$name]["name"] = $this->field_map_replace($field["filename"]);
- }
- else
- {
- $nb = 0;
- $name = $field["filename"];
- while (file_exists(PATH_ROOT."/".$field["folder"]."/".$_FILES[$name]["name"]))
- {
- $nb++;
- $_FILES[$name]["name"] = $nb."-".$name;
- }
- }
- $value = $_FILES[$name]["name"];
- }
- // Renommage sans fichier
- elseif ($value && (isset($field["filename"]) || !$this->$name || !file_exists(PATH_ROOT."/".$field["folder"]."/".$this->$name)))
- {
- //echo PATH_ROOT."/".$field["folder"]."/".$this->$name;
- unset($info[$name]);
- }
- }
- }
- }
- }
- //var_dump($_FILES); var_dump($info);
- }
- function field_map_replace($string)
- {
- $replace_from = $replace_to = array();
- foreach($this->_manager->_fields as $name=>$field)
- {
- $replace_from[] = "{".$name."}";
- $replace_to[] = $this->$name;
- }
- return str_replace($replace_from, $replace_to, $string);
- }
- /**
- * Contrôle supplémentaire à l'insertion
- * @param [] $info
- */
- public function field_verif_insert(&$info)
- {
- }
- /**
- * Contrôle supplémentaire à la mise à jour
- * @param [] $info
- */
- public function field_verif_update(&$info)
- {
- }
- /**
- * Update object with data
- * @param [] $info
- */
- private function field_update(&$info)
- {
- if (!is_array($info))
- return;
- foreach($info as $name=>$value)
- if ($name=="id" || isset($this->_manager->_fields[$name]))
- $this->$name = $value;
- }
- public function duplicate()
- {
- }
- /* OPERATIONS */
- /**
- * Insertion objet
- * @param [] $info
- * @return bool
- */
- public function insert($info)
- {
- if (is_numeric($this->id))
- return;
- $this->field_verif($info);
- $this->field_calculated($info);
- $this->field_verif_insert($info);
- if (is_numeric($id=$this->db_insert($info)))
- {
- $this->id = $id;
- $this->field_update($info);
- return true;
- }
- else
- return false;
- }
- /**
- * Mise à jour objet
- * @param [] $info
- * @return bool
- */
- public function update($info)
- {
- if (!is_numeric($this->id))
- return;
- $this->field_verif($info);
- foreach($info as $name=>$value)
- if ($this->$name === $value && (!in_array($this->_manager->_fields[$name]["type"], array("img", "file")) || !isset($_FILES[$name])))
- unset($info[$name]);
- $this->field_verif_update($info);
- if ($this->db_update($info))
- {
- $this->field_update($info);
- return true;
- }
- else
- return false;
- }
- /**
- * Supression objet
- * @return bool
- */
- public function delete()
- {
- if (!is_numeric($this->id))
- return;
- return $this->db_delete($this->id);
- }
- /* DATABASE */
- /*
- * Comprend autant les opérations en base de donnée que sur le système de fichiers,
- * bref sur tout support de stockage de donnée (ce qui se tient logiquement)
- */
- /**
- * Retrieve object info from database
- * @param int $id
- * @return []|bool
- */
- protected function db_retrieve($id)
- {
- if (!is_numeric($id) || !count($list=$this->_manager->db_retrieve("`".$this->_manager->_db_id."`='".$id."'")))
- return false;
- return array_pop($list);
- }
- /**
- * Update object in database
- * @param [] $info
- * @return int
- */
- protected function db_update($info)
- {
- if (!is_numeric($this->id))
- return false;
- $q_list = array();
- $file_move_list = $file_rename_list = $file_delete_list = array();
- //var_dump($_FILES); var_dump($info);
- foreach($info as $name=>$value)
- {
- $field = $this->_manager->_fields[$name];
- if (isset($field["type"]))
- {
- $type = $field["type"];
- if (in_array($field["type"], $this->_manager->field_simple))
- {
- if ($field["type"] == "select_multiple")
- {
- if (is_array($value))
- foreach($value as $i=>$v)
- $value[$i] = mysql_real_escape_string($v);
- $q_list[] = "`".(isset($field["db_fieldname"]) ?$field["db_fieldname"] :$name)."` = ".(is_array($value)&&count($value) ?"'".implode(",",$value)."'" :"NULL");
- }
- else
- $q_list[] = "`".(isset($field["db_fieldname"]) ?$field["db_fieldname"] :$name)."` = ".($value===NULL?"NULL":"'".mysql_real_escape_string($value)."'");
- if ($type == "img")
- {
- if (isset($_FILES[$name]) && $this->$name)
- $file_delete_list[] = PATH_ROOT."/".$field["folder"]."/".$this->$name;
- if (!isset($_FILES[$name]) && $this->$name)
- $file_rename_list[PATH_ROOT."/".$field["folder"]."/".$this->$name] = PATH_ROOT."/".$field["folder"]."/".$value;
- if (isset($_FILES[$name]))
- $file_move_list[$_FILES[$name]["tmp_name"]] = PATH_ROOT."/".$field["folder"]."/".$value;
- }
- }
- }
- }
- if (count($q_list)){
- $q_s = "UPDATE `".$this->_manager->_db_table."` SET ".implode(", ", $q_list)." WHERE `".$this->_manager->_db_id."`='".$this->id."'";
- $q_r = mysql_query($q_s);
- }
- if ($this->_manager->DB_DEBUG == true || (isset($q_s) && ($error=mysql_error())))
- {
- echo "$q_s : ".$error;
- }
- $return = (isset($q_s) && mysql_affected_rows()>0 ?true :false);
- if ($return)
- {
- foreach($file_delete_list as $name)
- {
- if ($this->_manager->FILE_DEBUG)
- echo "<p>Delete $name</p>\n";
- unlink($name);
- }
- foreach($file_rename_list as $from=>$to)
- {
- if ($this->_manager->FILE_DEBUG)
- echo "<p>Rename $from $to</p>\n";
- rename($from, $to);
- }
- foreach($file_move_list as $from=>$to)
- {
- if ($this->_manager->FILE_DEBUG)
- echo "<p>Move uplodaed $from $to</p>\n";
- move_uploaded_file($from, $to);
- }
- }
- // More fields
- $return = ($this->db_update_more($info) || $return);
- return $return;
- }
- /**
- * Modification supplémentaire
- * @param [] $info
- */
- protected function db_update_more($info)
- {
- return false;
- }
- /**
- * Insert in database
- * @param [] $info
- * @return bool
- */
- protected function db_insert($info)
- {
- if (is_numeric($this->id))
- return false;
- $q_list_1 = $q_list_2 = array();
- $file_move_list = array();
- foreach($info as $name=>$value)
- {
- $field = $this->_manager->_fields[$name];
- if (isset($field["type"]))
- {
- if (in_array($field["type"], $this->_manager->field_simple))
- {
- $type = $field["type"];
- $q_list_1[] = "`".(isset($field["db_fieldname"]) ?$field["db_fieldname"] : $name)."`";
- if ($field["type"] == "select_multiple")
- {
- if (is_array($value))
- foreach($value as $i=>$v)
- $value[$i] = "'".mysql_real_escape_string($v)."'";
- $q_list_2[] = (is_array($value)&&count($value) ?"(".implode(",",$value).")" :"NULL");
- }
- else
- $q_list_2[] = ($value===NULL?"NULL":"'".mysql_real_escape_string($value)."'");
- if ($type == "img")
- {
- $file_move_list[$_FILES[$name]["tmp_name"]] = PATH_ROOT."/".$field["folder"]."/".$value;
- }
- }
- }
- }
- $q_s = "INSERT INTO `".$this->_manager->_db_table."` (".implode(", ", $q_list_1).") VALUES (".implode(", ", $q_list_2).")";
- $q_r = mysql_query($q_s);
- if ($this->_manager->DB_DEBUG == true)
- {
- echo "$q_s : ".mysql_error();
- }
- $return = mysql_insert_id();
- if ($return)
- {
- foreach($file_move_list as $from=>$to)
- {
- if ($this->_manager->FILE_DEBUG)
- echo "<p>Move uploaded $from $to</p>\n";
- move_uploaded_file($from, $to);
- }
- }
- if ($return)
- $this->db_insert_more($return, $info);
- return $return;
- }
- /**
- * Insertions supplémentaires
- * @param int $id
- * @param [] $info
- * @return bool
- */
- protected function db_insert_more($id, $info)
- {
- return false;
- }
- /**
- * Delete object in database
- * @return bool
- */
- protected function db_delete()
- {
- if (!is_numeric($this->id))
- return false;
- $q_s = "DELETE FROM `".$this->_manager->_db_table."` WHERE `".$this->_manager->_db_id."`='".$this->id."'";
- $q_r = mysql_query($q_s);
- if ($this->_manager->DB_DEBUG == true)
- {
- echo "$q_s : ".mysql_error();
- }
- $return = (mysql_affected_rows()>0 ?true :false);
- if ($return)
- $this->db_delete_more();
- return $return;
- }
- /**
- * Suppressions supplémentaires
- * @return bool
- */
- protected function db_delete_more()
- {
- return false;
- }
- }
- ?>
|