Ubiquity  2.0.0
php rapid development framework
DAO.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Ubiquity\orm;
4 
11 
18 class DAO extends DAOUpdatesTrait {
22  public static $db;
23 
30  public static function getManyToOne($instance, $member, $useCache=NULL) {
31  $fieldAnnot=OrmUtils::getMemberJoinColumns($instance, $member);
32  if($fieldAnnot!==null){
33  $field=$fieldAnnot[0];
34  $value=Reflexion::getMemberValue($instance, $field);
35  $annotationArray=$fieldAnnot[1];
36  $member=$annotationArray["member"];
37  $key=OrmUtils::getFirstKey($annotationArray["className"]);
38  $kv=array ($key => $value );
39  $obj=self::getOne($annotationArray["className"], $kv, false, false, $useCache);
40  if ($obj !== null) {
41  Logger::log("getManyToOne", "Chargement de " . $member . " pour l'objet " . \get_class($instance));
42  $accesseur="set" . ucfirst($member);
43  if (method_exists($instance, $accesseur)) {
44  $instance->$accesseur($obj);
45  $instance->_rest[$member]=$obj->_rest;
46  return;
47  }
48  }
49  }
50  }
51 
52  private static function _getOneToManyFromArray(&$ret, $array, $fkv, $mappedBy) {
53  $elementAccessor="get" . ucfirst($mappedBy);
54  foreach ( $array as $element ) {
55  $elementRef=$element->$elementAccessor();
56  if (!is_null($elementRef)) {
57  $idElementRef=OrmUtils::getFirstKeyValue($elementRef);
58  if ($idElementRef == $fkv)
59  $ret[]=$element;
60  }
61  }
62  }
63 
71  public static function getOneToMany($instance, $member, $useCache=NULL, $annot=null) {
72  $ret=array ();
73  $class=get_class($instance);
74  if (!isset($annot))
75  $annot=OrmUtils::getAnnotationInfoMember($class, "#oneToMany", $member);
76  if ($annot !== false) {
77  $fkAnnot=OrmUtils::getAnnotationInfoMember($annot["className"], "#joinColumn", $annot["mappedBy"]);
78  if ($fkAnnot !== false) {
79  $fkv=OrmUtils::getFirstKeyValue($instance);
80  $ret=self::getAll($annot["className"], $fkAnnot["name"] . "='" . $fkv . "'", true, false, $useCache);
81  self::setToMember($member, $instance, $ret, $class, "getOneToMany");
82  }
83  }
84  return $ret;
85  }
86 
93  public static function affectsOneToManyFromArray($instance, $member, $array=null, $mappedBy=null) {
94  $ret=array ();
95  $class=get_class($instance);
96  if (!isset($mappedBy)){
97  $annot=OrmUtils::getAnnotationInfoMember($class, "#oneToMany", $member);
98  $mappedBy=$annot["mappedBy"];
99  }
100  if ($mappedBy !== false) {
101  $fkv=OrmUtils::getFirstKeyValue($instance);
102  self::_getOneToManyFromArray($ret, $array, $fkv, $mappedBy);
103  self::setToMember($member, $instance, $ret, $class, "getOneToMany");
104  }
105  return $ret;
106  }
107 
108  private static function setToMember($member, $instance, $value, $class, $part) {
109  $accessor="set" . ucfirst($member);
110  if (method_exists($instance, $accessor)) {
111  Logger::log($part, "Affectation de " . $member . " pour l'objet " . $class);
112  $instance->$accessor($value);
113  $instance->_rest[$member]=$value;
114  } else {
115  Logger::warn($part, "L'accesseur " . $accessor . " est manquant pour " . $class);
116  }
117  }
118 
127  public static function getManyToMany($instance, $member,$array=null,$useCache=NULL){
128  $ret=array ();
129  $class=get_class($instance);
130  $parser=new ManyToManyParser($instance, $member);
131  if ($parser->init()) {
132  if (is_null($array)) {
133  $accessor="get" . ucfirst($parser->getMyPk());
134  $condition=" INNER JOIN `" . $parser->getJoinTable() . "` on `".$parser->getJoinTable()."`.`".$parser->getFkField()."`=`".$parser->getTargetEntityTable()."`.`".$parser->getPk()."` WHERE `" . $parser->getMyFkField() . "`='" . $instance->$accessor() . "'";
135  $ret=self::getAll($parser->getTargetEntityClass(),$condition,true,false,$useCache);
136  }else{
137  self::getManyToManyFromArray($ret, $instance, $array, $class, $parser);
138  }
139  self::setToMember($member, $instance, $ret, $class, "getManyToMany");
140  }
141  return $ret;
142  }
143 
149  public static function affectsManyToManys($instance,$array=NULL,$useCache=NULL){
150  $metaDatas=OrmUtils::getModelMetadata(\get_class($instance));
151  $manyToManyFields=$metaDatas["#manyToMany"];
152  if(\sizeof($manyToManyFields)>0){
153  foreach ($manyToManyFields as $member){
154  self::getManyToMany($instance, $member,$array,$useCache);
155  }
156  }
157  }
158 
159  private static function getManyToManyFromArray(&$ret, $instance, $array, $class, $parser) {
160  $continue=true;
161  $accessorToMember="get" . ucfirst($parser->getInversedBy());
162  $myPkAccessor="get" . ucfirst($parser->getMyPk());
163 
164  if (!method_exists($instance, $myPkAccessor)) {
165  Logger::warn("ManyToMany", "L'accesseur au membre clĂ© primaire " . $myPkAccessor . " est manquant pour " . $class);
166  }
167  if (count($array) > 0)
168  $continue=method_exists($array[0], $accessorToMember);
169  if ($continue) {
170  foreach ( $array as $targetEntityInstance ) {
171  $instances=$targetEntityInstance->$accessorToMember();
172  if (is_array($instances)) {
173  foreach ( $instances as $inst ) {
174  if ($inst->$myPkAccessor() == $instance->$myPkAccessor())
175  array_push($ret, $targetEntityInstance);
176  }
177  }
178  }
179  } else {
180  Logger::warn("ManyToMany", "L'accesseur au membre " . $parser->getInversedBy() . " est manquant pour " . $parser->getTargetEntity());
181  }
182  }
183 
193  public static function getAll($className, $condition='', $loadManyToOne=true, $loadOneToMany=false,$useCache=NULL) {
194  $objects=array ();
195  $invertedJoinColumns=null;
196  $oneToManyFields=null;
197  $metaDatas=OrmUtils::getModelMetadata($className);
198  $tableName=$metaDatas["#tableName"];
199  if ($loadManyToOne && isset($metaDatas["#invertedJoinColumn"]))
200  $invertedJoinColumns=$metaDatas["#invertedJoinColumn"];
201  if ($loadOneToMany && isset($metaDatas["#oneToMany"])) {
202  $oneToManyFields=$metaDatas["#oneToMany"];
203  }
204  $condition=SqlUtils::checkWhere($condition);
205  $members=\array_diff($metaDatas["#fieldNames"],$metaDatas["#notSerializable"]);
206  $query=self::$db->prepareAndExecute($tableName, $condition,$members,$useCache);
207  Logger::log("getAll", "SELECT * FROM " . $tableName . $condition);
208  $oneToManyQueries=[];
209  $manyToOneQueries=[];
210 
211  foreach ( $query as $row ) {
212  $object=self::loadObjectFromRow($row, $className, $invertedJoinColumns, $oneToManyFields,$members, $oneToManyQueries,$manyToOneQueries);
213  $key=OrmUtils::getFirstKeyValue($object);
214  $objects[$key]=$object;
215  }
216 
217  if($loadManyToOne && \sizeof($manyToOneQueries)>0){
218  self::_affectsObjectsFromArray($manyToOneQueries, $objects, function($object,$member,$manyToOneObjects,$fkField){
219  self::affectsManyToOneFromArray($object,$member,$manyToOneObjects,$fkField);
220  });
221  }
222 
223  if($loadOneToMany && \sizeof($oneToManyQueries)>0){
224  self::_affectsObjectsFromArray($oneToManyQueries, $objects, function($object,$member,$relationObjects,$fkField){
225  self::affectsOneToManyFromArray($object,$member,$relationObjects,$fkField);
226  });
227  }
228  return $objects;
229  }
230 
231  private static function _affectsObjectsFromArray($queries,$objects,$affectsCallback,$useCache=NULL){
232  foreach ($queries as $key=>$conditions){
233  list($class,$member,$fkField)=\explode("|", $key);
234  $condition=\implode(" OR ", $conditions);
235  $relationObjects=self::getAll($class,$condition,true,false,$useCache);
236  foreach ($objects as $object){
237  $affectsCallback($object, $member,$relationObjects,$fkField);
238  }
239  }
240  }
241 
242  private static function affectsManyToOneFromArray($object,$member,$manyToOneObjects,$fkField){
243  $class=\get_class($object);
244  if(isset($object->$fkField)){
245  $value=$manyToOneObjects[$object->$fkField];
246  self::setToMember($member, $object, $value, $class, "getManyToOne");
247  }
248  }
249 
260  private static function loadObjectFromRow($row, $className, $invertedJoinColumns, $oneToManyFields, $members,&$oneToManyQueries,&$manyToOneQueries) {
261  $o=new $className();
262  foreach ( $row as $k => $v ) {
263  if(($field=\array_search($k, $members))!==false){
264  $accesseur="set" . ucfirst($field);
265  if (method_exists($o, $accesseur)) {
266  $o->$accesseur($v);
267  }
268  }
269  $o->_rest[$k]=$v;
270  if (isset($invertedJoinColumns) && isset($invertedJoinColumns[$k])) {
271  $fk="_".$k;
272  $o->$fk=$v;
273  self::prepareManyToOne($manyToOneQueries,$v, $fk,$invertedJoinColumns[$k]);
274  }
275  }
276  if (isset($oneToManyFields)) {
277  foreach ( $oneToManyFields as $k => $annot ) {
278  self::prepareOneToMany($oneToManyQueries,$o, $k, $annot);
279  }
280  }
281  return $o;
282  }
283 
284 
292  private static function prepareOneToMany(&$ret,$instance, $member, $annot=null) {
293  $class=get_class($instance);
294  if (!isset($annot))
295  $annot=OrmUtils::getAnnotationInfoMember($class, "#oneToMany", $member);
296  if ($annot !== false) {
297  $fkAnnot=OrmUtils::getAnnotationInfoMember($annot["className"], "#joinColumn", $annot["mappedBy"]);
298  if ($fkAnnot !== false) {
299  $fkv=OrmUtils::getFirstKeyValue($instance);
300  $key=$annot["className"]."|".$member."|".$annot["mappedBy"];
301  if(!isset($ret[$key])){
302  $ret[$key]=[];
303  }
304  $ret[$key][$fkv]=$fkAnnot["name"] . "='" . $fkv . "'";
305  }
306  }
307  }
308 
316  private static function prepareManyToOne(&$ret, $value, $fkField,$annotationArray) {
317  $member=$annotationArray["member"];
318  $fk=OrmUtils::getFirstKey($annotationArray["className"]);
319  $key=$annotationArray["className"]."|".$member."|".$fkField;
320  if(!isset($ret[$key])){
321  $ret[$key]=[];
322  }
323  $ret[$key][$value]=$fk . "='" . $value . "'";
324  }
325 
332  public static function count($className, $condition='') {
333  $tableName=OrmUtils::getTableName($className);
334  if ($condition != '')
335  $condition=" WHERE " . $condition;
336  return self::$db->query("SELECT COUNT(*) FROM " . $tableName . $condition)->fetchColumn();
337  }
338 
348  public static function getOne($className, $keyValues, $loadManyToOne=true, $loadOneToMany=false, $useCache=NULL) {
349  if (!is_array($keyValues)) {
350  if (strrpos($keyValues, "=") === false && strrpos($keyValues, ">") === false && strrpos($keyValues, "<") === false) {
351  $keyValues="`" . OrmUtils::getFirstKey($className) . "`='" . $keyValues . "'";
352  }
353  }
354  $condition=SqlUtils::getCondition($keyValues,$className);
355  $limit="";
356  if(\stripos($condition, " limit ")===false)
357  $limit=" limit 1";
358  $retour=self::getAll($className, $condition.$limit, $loadManyToOne, $loadOneToMany,$useCache);
359  if (sizeof($retour) < 1){
360  return null;
361  }
362  return \reset($retour);
363  }
364 
376  public static function connect($dbType,$dbName, $serverName="127.0.0.1", $port="3306", $user="root", $password="", $options=[],$cache=false) {
377  self::$db=new Database($dbType,$dbName, $serverName, $port, $user, $password, $options,$cache);
378  try {
379  self::$db->connect();
380  } catch (\Exception $e) {
381  Logger::error("DAO", $e->getMessage());
382  throw $e;
383  }
384  }
385 
390  public static function isConnected(){
391  return self::$db!==null && (self::$db instanceof Database) && self::$db->isConnected();
392  }
393 }
static getMemberJoinColumns($instance, $member, $metaDatas=NULL)
Definition: OrmUtils.php:251
static _affectsObjectsFromArray($queries, $objects, $affectsCallback, $useCache=NULL)
Definition: DAO.php:231
static checkWhere($condition)
Definition: SqlUtils.php:63
static getManyToOne($instance, $member, $useCache=NULL)
Loads member associated with $instance by a ManyToOne type relationship.
Definition: DAO.php:30
Trait for DAO Updates (Create, Update, Delete)
static error($id, $message, $code=0)
Definition: Logger.php:32
static getOne($className, $keyValues, $loadManyToOne=true, $loadOneToMany=false, $useCache=NULL)
Returns an instance of $className from the database, from $keyvalues values of the primary key...
Definition: DAO.php:348
static setToMember($member, $instance, $value, $class, $part)
Definition: DAO.php:108
static getAnnotationInfoMember($class, $keyAnnotation, $member)
Definition: OrmUtils.php:200
static $db
Definition: DAO.php:22
static connect($dbType, $dbName, $serverName="127.0.0.1", $port="3306", $user="root", $password="", $options=[], $cache=false)
Establishes the connection to the database using the past parameters.
Definition: DAO.php:376
static getCondition($keyValues, $classname=NULL, $separator=" AND ")
Definition: SqlUtils.php:71
static affectsOneToManyFromArray($instance, $member, $array=null, $mappedBy=null)
Definition: DAO.php:93
static getFirstKey($class)
Definition: OrmUtils.php:121
static getManyToManyFromArray(&$ret, $instance, $array, $class, $parser)
Definition: DAO.php:159
static prepareManyToOne(&$ret, $value, $fkField, $annotationArray)
Prepares members associated with $instance with a manyToOne type relationship.
Definition: DAO.php:316
static getFirstKeyValue($instance)
Definition: OrmUtils.php:126
static getManyToMany($instance, $member, $array=null, $useCache=NULL)
Assigns / loads the child records in the $member member of $instance.
Definition: DAO.php:127
static getAll($className, $condition='', $loadManyToOne=true, $loadOneToMany=false, $useCache=NULL)
Returns an array of $className objects from the database.
Definition: DAO.php:193
static count($className, $condition='')
Returns the number of objects of $className from the database respecting the condition possibly passe...
Definition: DAO.php:332
static getMemberValue($instance, $member)
Definition: Reflexion.php:35
static isConnected()
Returns true if the connection to the database is estabished.
Definition: DAO.php:390
static log($id, $message, $code=0)
Definition: Logger.php:22
static getModelMetadata($className)
Definition: OrmUtils.php:18
static getTableName($class)
Definition: OrmUtils.php:61
static warn($id, $message, $code=0)
Definition: Logger.php:27
static affectsManyToOneFromArray($object, $member, $manyToOneObjects, $fkField)
Definition: DAO.php:242
static getOneToMany($instance, $member, $useCache=NULL, $annot=null)
Assign / load the child records in the $member member of $instance.
Definition: DAO.php:71
static prepareOneToMany(&$ret, $instance, $member, $annot=null)
Prepares members associated with $instance with a oneToMany type relationship.
Definition: DAO.php:292
static loadObjectFromRow($row, $className, $invertedJoinColumns, $oneToManyFields, $members, &$oneToManyQueries, &$manyToOneQueries)
Definition: DAO.php:260
static _getOneToManyFromArray(&$ret, $array, $fkv, $mappedBy)
Definition: DAO.php:52
static affectsManyToManys($instance, $array=NULL, $useCache=NULL)
Definition: DAO.php:149