nyroFwk  0.2
table.class.php
Go to the documentation of this file.
1 <?php
10 class db_table extends object {
11 
17  protected $rawName;
18 
24  protected $fields = array();
25 
31  protected $cols = array();
32 
38  protected $linkedTables;
39 
45  protected $linkedTableNames;
46 
52  protected $relatedTables;
53 
59  protected $targetingTables;
60 
66  protected $i18nTable;
67 
68  protected function afterInit() {
69  $defaultClass = 'db_table_'.$this->cfg->name;
70  if (get_class($this) != $defaultClass)
71  $this->cfg->overload($defaultClass);
72  $this->rawName = $this->cfg->db->prefixTable($this->cfg->name);
73  $this->_initi18n();
74  $this->_initFields();
75  $this->_initIdent();
76  $this->_initLinkedTables();
77  $this->_initRelatedTables();
78  $this->_initLabels();
79  }
80 
84  protected function _initI18n() {
85  if ($i18ntable = $this->getDb()->getI18nTable($this->getRawName())) {
86  $this->i18nTable = db::get('table', $i18ntable, array(
87  'name'=>$i18ntable,
88  'db'=>$this->getDb()
89  ));
90  }
91  }
92 
98  public function isI18n() {
99  return strpos($this->getName(), db::getCfg('i18n')) > 0;
100  }
101 
107  public function hasI18n() {
108  return !is_null($this->i18nTable);
109  }
110 
116  public function getI18nTable() {
117  return $this->i18nTable;
118  }
119 
125  public function getI18nFields() {
126  $tmp = array();
127  if ($this->i18nTable) {
128  foreach($this->i18nTable->getField() as $f) {
129  if (!$f['primary'])
130  $tmp[] = $f;
131  }
132  }
133  return $tmp;
134  }
135 
139  protected function _initFields() {
140  $this->fields = $this->getDb()->fields($this->cfg->name);
141  $this->cols = array_keys($this->fields);
142 
143  if (array_key_exists($this->cfg->inserted, $this->fields))
144  $this->fields[$this->cfg->inserted]['auto'] = true;
145 
146  if (array_key_exists($this->cfg->updated, $this->fields))
147  $this->fields[$this->cfg->updated]['auto'] = true;
148 
149  if (array_key_exists($this->cfg->deleted, $this->fields))
150  $this->fields[$this->cfg->deleted]['auto'] = true;
151 
152  if ($this->cfg->check('fields') && is_array($this->cfg->fields) && !empty($this->cfg->fields)) {
153  factory::mergeCfg($this->fields, array_intersect_key($this->cfg->fields, $this->fields));
154  foreach($this->fields as &$f) {
155  if (is_array($f['default']))
156  $f['default'] = array_key_exists(1, $f['default']) ? $f['default'][1] : $f['default'][0];
157  }
158  }
159  }
160 
164  protected function _initIdent() {
165  if (empty($this->cfg->primary)) {
166  $primary = array();
167  foreach($this->fields as $n=>&$f)
168  if ($f['primary']) {
169  $primary[$f['primaryPos']] = $n;
170  if ($f['identity']) {
171  $this->cfg->ident = $n;
172  }
173  }
174  $this->cfg->primary = $primary;
175  } else if(is_string($this->cfg->primary))
176  $this->cfg->primary = array($this->cfg->primary);
177  }
178 
182  protected function _initLinkedTables() {
183  if ($this->linkedTables === null && !$this->isI18n()) {
184  $this->linkedTables = array();
185  $this->linkedTableNames = array();
186  foreach($this->cols as $c) {
187  if (strpos($c, '_') && $this->fields[$c]['type'] != 'file') {
188  $tmp = explode('_', $c);
189  $num = is_numeric($tmp[0])? array_shift($tmp) : 1;
190  $table = array_shift($tmp);
191  $fields = array();
192  $i18nFields = array();
193  foreach($tmp as $t) {
194  if (db::isI18nName($t))
195  $i18nFields[] = db::unI18nName($t);
196  else
197  $fields[] = $t;
198  }
199  $list = array();
200  $sep = $this->cfg->defSep;
201  $nbFieldGr = 0;
202  $sepGr = null;
203  $more = array();
204  if (!empty($this->fields[$c]['comment'])) {
205  $com = $this->fields[$c]['comment'];
206  foreach($com as $kk=>$cc) {
207  if (!is_numeric($kk)) {
208  $more[$kk] = $cc;
209  unset($com[$kk]);
210  }
211  }
212  $sep = !empty($com[0])? array_shift($com) : $this->cfg->defSep;
213  $list = array(array_shift($com));
214  $nbFieldGr = array_shift($com);
215  $sepGr = array_shift($com);
216  }
217  $this->linkedTableNames[$c] = $table;
218  $this->linkedTables[$c] = array_merge(array(
219  'field'=>$c,
220  'table'=>$table,
221  'ident'=>$this->cfg->defId,
222  'fields'=>implode(',', $fields),
223  'i18nFields'=>implode(',', $i18nFields),
224  'label'=>ucfirst($table),
225  'num'=>$num,
226  'sep'=>$sep,
227  'list'=>$list,
228  'nbFieldGr'=>$nbFieldGr,
229  'sepGr'=>$sepGr,
230  'where'=>null,
231  ), $more);
232  }
233  }
234  }
235 
236  if ($this->cfg->check('linked') && is_array($this->cfg->linked) && !empty($this->cfg->linked))
237  factory::mergeCfg($this->linkedTables, $this->cfg->linked);
238  }
239 
245  public function getDb() {
246  return $this->cfg->db;
247  }
248 
255  public function getWhere(array $prm = array()) {
256  return $this->getDb()->getWhere($prm);
257  }
258 
265  public function isLinked($field) {
266  return is_array($this->linkedTables) && array_key_exists($field, $this->linkedTables);
267  }
268 
275  public function getLinkedTableName($tablename) {
276  if (is_array($this->linkedTableNames)) {
277  $key = array_search($tablename, $this->linkedTableNames);
278  if ($key)
279  return $this->getLinked($key);
280  }
281  return null;
282  }
283 
290  public function getLinked($field = null) {
291  if (is_null($field))
292  return $this->linkedTables;
293 
294  if ($this->isLinked($field))
295  return $this->linkedTables[$field];
296  return null;
297  }
298 
305  public function getLinkedTable($field) {
306  if ($link = $this->getLinked($field)) {
307  if (!array_key_exists('tableObj', $link))
308  $link['tableObject'] = db::get('table', $link['table'], array(
309  'db'=>$this->getDb()
310  ));
311  return $link['tableObject'];
312  }
313  return null;
314  }
315 
323  public function getLinkedTableRow($field, array $data = array()) {
324  if ($table = $this->getLinkedTable($field))
325  return $table->getRow($data, false, array('needReload'=>true));
326  return null;
327  }
328 
332  protected function _initRelatedTables() {
333  if (is_null($this->relatedTables)) {
334  $this->relatedTables = array();
335  $search = $this->rawName.'_';
336  $tables = $this->getDb()->getTablesWith(array('start'=>$search));
337  foreach($tables as $t) {
338  $relatedTable = substr($t, strlen($search));
339  $table = db::get('table', $t, array(
340  'db'=>$this->getDb()
341  ));
342  $fields = $table->getField();
343  $fk1 = $fk2 = null;
344  foreach($fields as $k=>$v) {
345  if (is_null($fk1) && strpos($k, $this->rawName) !== false) {
346  $fk1 = array_merge($v, array('link'=>$table->getLinked($k)));
347  unset($fields[$k]);
348  } else if (strpos($k, $relatedTable) !== false) {
349  $fk2 = array_merge($v, array('link'=>$table->getLinked($k)));
350  unset($fields[$k]);
351  }
352  }
353 
354  $this->relatedTables[$t] = array(
355  'tableObj'=>$table,
356  'tableLink'=>$t,
357  'table'=>$relatedTable,
358  'fk1'=>$fk1,
359  'fk2'=>$fk2,
360  'fields'=>$fields,
361  );
362  }
363  }
364  if ($this->cfg->check('related') && is_array($this->relatedTables) && !empty($this->relatedTables))
365  factory::mergeCfg($this->relatedTables, $this->cfg->related);
366  }
367 
374  public function isRelated($name) {
375  return array_key_exists($this->getRelatedTableName($name), $this->relatedTables);
376  }
377 
384  public function getRelated($name = null) {
385  if (is_null($name))
386  return $this->relatedTables;
387 
388  $name = $this->getRelatedTableName($name);
389  return $this->isRelated($name)? $this->relatedTables[$name] : null;
390  }
391 
399  public function getRelatedTableRow($name, array $data = array()) {
400  if ($table = $this->getRelatedTable($name))
401  return $table->getRow($data);
402  return null;
403  }
404 
411  public function getRelatedTable($name) {
412  if ($related = $this->getRelated($this->getRelatedTableName($name)))
413  return $related['tableObj'];
414  return null;
415  }
416 
424  public function getRelatedTableName($name, $add = true) {
425  $shouldStart = $this->getName().'_';
426  $pos = strpos($name, $shouldStart);
427  if ($pos !== 0 && $add)
428  $name = $shouldStart.$name;
429  else if ($pos === 0 && !$add)
430  $name = substr($name, strlen($shouldStart));
431 
432  return $name;
433  }
434 
440  public function getTargetingTables() {
441  if (is_null($this->targetingTables)) {
442  $tblName = $this->getName();
443  if ($this->cfg->cacheEnabled) {
444  $cache = $this->getDb()->getCache();
445  $cache->get($this->targetingTables, array('id'=>$tblName));
446  }
447 
448  if (is_null($this->targetingTables)) {
449  $this->targetingTables = array();
450  foreach($this->getDb()->getTables() as $tbl) {
451  if ($tbl != $tblName && db::get('table', $tbl)->isTargeting($tblName)) {
452  $this->targetingTables[] = $tbl;
453  $tmpPos = strpos($tbl, $tblName.'_');
454  if ($tmpPos === 0)
455  $this->targetingTables[] = substr($tbl, strlen($tblName)+1);
456  }
457  }
458  if ($this->cfg->cacheEnabled)
459  $cache->save();
460  }
461  }
462  return $this->targetingTables;
463  }
464 
471  public function isTargeting($tableName) {
472  if (strpos($this->getName(), '_') !== false) {
473  $tmp = explode('_', $this->getName());
474  if ($tmp[0] == $tableName || $tmp[1] == $tableName)
475  return true;
476  }
477 
478  if (is_array($this->getLinked())) {
479  foreach($this->getLinked() as $linked) {
480  if ($linked['table'] == $tableName)
481  return true;
482  }
483  }
484 
485  if (is_array($this->getRelated())) {
486  foreach($this->getRelated() as $related) {
487  if ($related['tableObj']->isTargeting($tableName))
488  return true;
489  }
490  }
491 
492  return false;
493  }
494 
498  protected function _initLabels() {
499  $labels = array();
500  $cfgLabel = $this->cfg->label;
501  foreach($this->cols as $c) {
502  if (array_key_exists($c, $cfgLabel) && $label = $cfgLabel[$c]) {
503  $labels[$c] = utils::htmlOut($label);
504  unset($cfgLabel[$c]);
505  } else if($this->fields[$c]['type'] == 'file')
506  $labels[$c] = ucwords(str_replace('_', ' ', strtolower(substr($c, 0, -5))));
507  else {
508  $use = $c;
509  $pos = strpos($c, '_');
510  if ($pos) {
511  $start = 0;
512  if ($pos == 1) {
513  $start = 2;
514  $pos = strpos($c, '_', $start) - $start;
515  }
516  $use = substr($c, $start, $pos);
517  }
518  $labels[$c] = ucwords(strtolower($use));
519  }
520  $this->fields[$c]['label'] = $labels[$c];
521  }
522  foreach($this->relatedTables as $r) {
523  if (array_key_exists($r['table'], $cfgLabel) && $label = $cfgLabel[$r['table']]) {
524  $labels[$r['table']] = utils::htmlOut($label);
525  unset($cfgLabel[$r['table']]);
526  } else
527  $labels[$r['table']] = ucwords(str_replace('_', ' ', strtolower($r['table'])));
528  }
529  $this->cfg->label = array_merge($labels, $cfgLabel);
530  }
531 
538  public function getLabel($field = null) {
539  if (db::isI18nName($field))
540  return $this->getI18nLabel(db::unI18nName($field));
541 
542  if (is_null($field))
543  return $this->cfg->label;
544 
545  $field = $this->isRelated($field)? $this->getRelatedTableName($field, false) : $field;
546  return $this->cfg->getInArray('label', $field);
547  }
548 
555  public function getI18nLabel($field = null) {
556  return $this->i18nTable->getLabel($field);
557  }
558 
566  public function getField($field = null, $keyVal = null) {
567  if (is_null($field))
568  return $this->fields;
569 
570  $ret = array_key_exists($field, $this->fields) ? $this->fields[$field] : null;
571  if (!is_null($keyVal) && is_array($ret) && array_key_exists($keyVal, $ret))
572  return $ret[$keyVal];
573  return $ret ? $ret : $this->cfg->getInArray('label', $field);
574  }
575 
581  public function getFieldFile() {
582  $ret = null;
583  foreach($this->fields as $f) {
584  if ($f['type'] == 'file')
585  $ret[] = $f['name'];
586  }
587  return $ret;
588  }
589 
595  public function getCols() {
596  return $this->cols;
597  }
598 
604  public function getName() {
605  return $this->cfg->name;
606  }
607 
613  public function getRawName() {
614  return $this->rawName;
615  }
616 
622  public function getIdent() {
623  return $this->cfg->ident;
624  }
625 
631  public function getPrimary() {
632  return $this->cfg->primary;
633  }
634 
642  public function insert(array $data) {
643  unset($data[$this->getIdent()]);
644  $this->dateAutoData($data, 'inserted');
645  $this->dateAutoData($data, 'updated');
646  $ret = $this->getDb()->insert(array(
647  'table'=>$this->rawName,
648  'values'=>$data
649  ));
650  if ($ret)
651  $this->clearCache();
652  return $ret;
653  }
654 
662  public function replace(array $data) {
663  unset($data[$this->getIdent()]);
664  $this->dateAutoData($data, 'inserted');
665  $this->dateAutoData($data, 'updated');
666  $ret = $this->getDb()->replace(array(
667  'table'=>$this->rawName,
668  'values'=>$data
669  ));
670  if ($ret)
671  $this->clearCache();
672  return $ret;
673  }
674 
683  public function update(array $data, $where = null) {
684  $this->dateAutoData($data, 'updated');
685  $ret = $this->getDb()->update(array(
686  'table'=>$this->rawName,
687  'values'=>$data,
688  'where'=>$where
689  ));
690  if ($ret)
691  $this->clearCache();
692  return $ret;
693  }
694 
702  public function delete($where = null) {
703  $ret = 0;
704  $data = array();
705  $this->dateAutoData($data, 'deleted');
706  if (empty($data)) {
707  if ($files = $this->getFieldFile()) {
708  $rows = $this->select(array('autoJoin'=>false, 'where'=>$where));
709  if ($this->cfg->deleteCheckFile) {
710  $fields = array();
711  foreach($rows as $r) {
712  foreach($files as $f) {
713  if (!isset($fields[$f.'-'.$r->get($f)])) {
714  $form = $r->getForm(array($f));
715  $fields[$f.'-'.$r->get($f)] = array(
716  'formValue'=>$form->get($f)->getRawValue(),
717  'exist'=>$this->count(array('autoJoin'=>false, 'where'=>array($f=>$r->get($f)))),
718  'delete'=>0
719  );
720  }
721  $fields[$f.'-'.$r->get($f)]['delete']++;
722  }
723  }
724  foreach($fields as $f) {
725  if ($f['exist'] == $f['delete'])
726  $f['formValue']->delete();
727  }
728  } else {
729  foreach($rows as $r) {
730  $form = $r->getForm($files);
731  foreach($files as $f)
732  $form->get($f)->getRawValue()->delete();
733  }
734  }
735  }
736  $ret = $this->getDb()->delete(array(
737  'table'=>$this->rawName,
738  'where'=>$where,
739  'optim'=>$this->cfg->optimAfterDelete
740  ));
741  } else {
742  $ret = $this->getDb()->update(array(
743  'table'=>$this->rawName,
744  'values'=>$data,
745  'where'=>$where,
746  'optim'=>$this->cfg->optimAfterDelete
747  ));
748  }
749  if ($ret)
750  $this->clearCache();
751  return $ret;
752  }
753 
761  public function dateAutoData(array &$data, $type) {
762  if ($fieldName = $this->cfg->get($type)) {
763  if (array_key_exists($fieldName, $this->fields) && !array_key_exists($fieldName, $data)) {
764  $data[$fieldName] = $this->dateValue($this->fields[$fieldName]['type']);
765  return true;
766  }
767  }
768  return false;
769  }
770 
777  protected function dateValue($type) {
778  $ret = time();
779  switch($type) {
780  case 'date':
781  $ret = date('Y-m-d');
782  break;
783  case 'datetime':
784  $ret = date('Y-m-d H:i:s');
785  break;
786  }
787  return $ret;
788  }
789 
799  public function select(array $prm = array()) {
800  $prm = $this->selectQuery($prm, $tmpTables);
801 
802  $ret = array();
803  $cache = $this->getDb()->getCache();
804  $canCache = $this->cfg->cacheEnabled && (!isset($prm['order']) || !(stripos($prm['order'], 'rand(') !== false));
805  if (!$canCache || !$cache->get($ret, array('id'=>$this->getName().'-'.sha1(serialize($prm).'-'.serialize($tmpTables))))) {
806  $ret = $this->getDb()->select($prm);
807 
808  if (!empty($ret) && !empty($this->cfg->forceValues)) {
809  foreach($ret as $k=>$v)
810  $ret[$k] = array_merge($v, $this->cfg->forceValues);
811  }
812 
813  self::parseLinked($ret, $tmpTables);
814 
815  if ($canCache)
816  $cache->save();
817  }
818 
819  if (array_key_exists('first', $prm) && $prm['first']) {
820  if (!empty($ret))
821  return db::get('row', $this, array(
822  'db'=>$this->getDb(),
823  'data'=>$ret[0],
824  ));
825  else
826  return null;
827  } else
828  return db::get('rowset', $this, array(
829  'db'=>$this->getDb(),
830  'data'=>$ret,
831  ));
832  }
833 
840  public function count(array $prm) {
841  $prm = $this->selectQuery($prm, $tmpTables);
842  if ($this->getIdent())
843  $prm['group'] = $prm['fields'] = $this->rawName.'.'.$this->getIdent();
844  else
845  $prm['group'] = $prm['fields'] = $this->rawName.'.'.implode(','.$this->rawName.'.', $this->getPrimary());
846 
847  $prm['where'] = $this->getDb()->makeWhere($prm['where'], $prm['whereOp'], false);
848  $nb = array_key_exists('join', $prm) ? count($prm['join']) : 0;
849  for($i=0; $i<$nb; $i++) {
850  $table = array_key_exists('alias', $prm['join'][$i])
851  ? $prm['join'][$i]['alias']
852  : $prm['join'][$i]['table'];
853  if (array_key_exists('dir', $prm['join'][$i]) &&
854  !is_null(strpos($prm['join'][$i]['dir'], 'outer')) &&
855  !preg_match('/`'.$table.'`\./', $prm['where']))
856  unset($prm['join'][$i]);
857  }
858  return $this->getDb()->count($prm);
859  }
860 
867  public function selectQuery(array $prm, &$tmpTables) {
868  config::initTab($prm, array(
869  'where'=>'',
870  'whereOp'=>'AND',
871  'order'=>'',
872  'autoJoin'=>$this->cfg->autoJoin,
873  ));
874 
875  if (is_array($prm['where'])) {
876  foreach($prm['where'] as $k=>$v) {
877  if (!is_numeric($k) && strpos($k, '.') === false) {
878  $newK = $this->rawName.'.'.$k;
879  if (!array_key_exists($newK, $prm['where'])) {
880  $prm['where'][$newK] = $v;
881  unset($prm['where'][$k]);
882  }
883  }
884  }
885  } else if (!empty($prm['where']) && !is_array($prm['where']) && !is_object($prm['where'])
886  && (strpos($prm['where'], '=') === false && strpos($prm['where'], '<') === false
887  && strpos($prm['where'], '>') === false && stripos($prm['where'], 'LIKE') === false
888  && stripos($prm['where'], 'IN') === false)) {
889  $prm['where'] = $this->rawName.'.'.$this->cfg->ident.'='.$prm['where'];
890  }
891 
892  $prm = array_merge(array(
893  'fields'=>$this->getDb()->quoteIdentifier($this->rawName).'.*',
894  'table'=>$this->rawName,
895  ), $prm);
896 
897  if (is_array($prm['fields'])) {
898  array_walk($prm['fields'],
899  create_function('&$v', '$v = strpos($v, ".") === false? "'.$this->rawName.'.".$v: $v;'));
900  $prm['fields'] = implode(',', $prm['fields']);
901  }
902 
903  $join = isset($prm['join']) ? $prm['join'] : array();
904  $prm['join'] = array();
905  $tmpTables = array();
906  if (!empty($this->linkedTables) && $prm['autoJoin']) {
907  foreach($this->linkedTables as $f=>$p) {
908  $alias = $f;
909  $prm['join'][] = array(
910  'table'=>$p['table'],
911  'alias'=>$alias,
912  'dir'=>'left outer',
913  'on'=>$this->rawName.'.'.$f.'='.$alias.'.'.$p['ident']
914  );
915  $fields = explode(',', $p['fields']);
916  array_unshift($fields, $p['ident']);
917  $fields = array_flip(array_flip(array_filter($fields)));
918  $fieldsT = $fields;
919  array_walk($fieldsT, create_function('&$v', '$v = "'.$alias.'_".$v;'));
920  $tmpTables[$f] = $fieldsT;
921  $tmpTables[$f]['sep'] = $p['sep'];
922  $tmpTables[$f]['ident'] = $alias.'_'.$p['ident'];
923  $tmp = array();
924  $linkedTable = db::get('table', $p['table'], array(
925  'db'=>$this->getDb()
926  ));
927  foreach($fields as $t) {
928  if ($linkedInfo = $linkedTable->getLinkedTableName($t)) {
929  $aliasT = $alias.'_'.$linkedInfo['table'];
930  $prm['join'][] = array(
931  'table'=>$linkedInfo['table'],
932  'alias'=>$aliasT,
933  'dir'=>'left outer',
934  'on'=>$alias.'.'.$linkedInfo['field'].'='.$aliasT.'.'.$linkedInfo['ident']
935  );
936  $ttmp = array();
937  foreach(explode(',', $linkedInfo['fields']) as $tt) {
938  $ttmp[] = $aliasT.'.'.$tt;
939  $ttmp[] = '"'.$linkedInfo['sep'].'"';
940  }
941  array_pop($ttmp);
942  $tmp[] = 'CONCAT('.implode(',', $ttmp).') AS '.$alias.'_'.$t;
943  } else
944  $tmp[] = $alias.'.'.$t.' AS '.$alias.'_'.$t;
945  }
946  $fields = $tmp;
947  $prm['fields'].= ','.implode(',', $fields);
948 
949  if ($p['i18nFields']) {
950  $fieldsI18n = array();
951  $i18nTableName = $p['table'].db::getCfg('i18n');
952  $i18nTable = db::get('table', $i18nTableName, array('db'=>$this->getDb()));
953  $primary = $i18nTable->getPrimary();
954  $i18nAlias = $alias.db::getCfg('i18n');
955  $prm['join'][] = array(
956  'table'=>$i18nTableName,
957  'alias'=>$i18nAlias,
958  'dir'=>'left outer',
959  'on'=>$alias.'.'.$p['ident'].'='.$i18nAlias.'.'.$primary[0].
960  ' AND '.$i18nAlias.'.'.$primary[1].'="'.request::get('lang').'"'
961  );
962  $fields = explode(',', $p['i18nFields']);
963  $fields = array_flip(array_flip(array_filter($fields)));
964  $fieldsI18n = $fields;
965  array_walk($fieldsI18n, create_function('&$v', '$v = "'.$alias.'_'.db::getCfg('i18n').'".$v;'));
966  array_walk($fields, create_function('&$v', '$v = "'.$i18nAlias.'.".$v." AS '
967  .$alias.'_'.db::getCfg('i18n').'".$v;'));
968  $tmpTables[$f] = array_merge($tmpTables[$f], $fieldsI18n);
969  if (!empty($fields))
970  $prm['fields'].= ','.implode(',', $fields);
971  }
972  }
973  }
974 
975  if ((!empty($this->relatedTables) && $prm['autoJoin']) || $this->i18nTable) {
976  foreach($this->relatedTables as $f=>$p) {
977  $prm['join'][] = array(
978  'table'=>$f,
979  'dir'=>'left outer',
980  'on'=>$this->rawName.'.'.$p['fk1']['link']['ident'].'='.$f.'.'.$p['fk1']['name']
981  );
982 
983  // related Table fields
984  $fields = array_keys($p['fields']);
985  $fieldsTableLink = $fields;
986  array_walk($fieldsTableLink, create_function('&$v', '$v = "'.$f.'_".$v;'));
987  array_walk($fields, create_function('&$v', '$v = "'.$f.'.".$v." AS '.$f.'_".$v;'));
988  if (!empty($fields))
989  $prm['fields'].= ','.implode(',', $fields);
990 
991  $prm['join'][] = array(
992  'table'=>$p['table'],
993  'dir'=>'left outer',
994  'on'=>$f.'.'.$p['fk2']['name'].'='.$p['table'].'.'.$p['fk2']['link']['ident']
995  );
996 
997  // related Table fields
998  $fields = explode(',', $p['fk2']['link']['fields']);
999  array_unshift($fields, $p['fk2']['link']['ident']);
1000  $fields = array_flip(array_flip(array_filter($fields)));
1001  $fieldsT = $fields;
1002  array_walk($fieldsT, create_function('&$v', '$v = "'.$p['table'].'_".$v;'));
1003  array_walk($fields, create_function('&$v', '$v = "'.$p['table'].'.".$v." AS '.$p['table'].'_".$v;'));
1004  if (!empty($fields))
1005  $prm['fields'].= ','.implode(',', $fields);
1006 
1007  // i18n related Table fields
1008  if ($p['fk2']['link']['i18nFields']) {
1009  $fieldsI18n = array();
1010  $i18nTableName = $p['table'].db::getCfg('i18n');
1011  $i18nTable = db::get('table', $i18nTableName, array('db'=>$this->getDb()));
1012  $primary = $i18nTable->getPrimary();
1013  $prm['join'][] = array(
1014  'table'=>$i18nTableName,
1015  'dir'=>'left outer',
1016  'on'=>$f.'.'.$p['fk2']['name'].'='.$i18nTableName.'.'.$primary[0].
1017  ' AND '.$i18nTableName.'.'.$primary[1].'="'.request::get('lang').'"'
1018  );
1019  $fields = explode(',', $p['fk2']['link']['i18nFields']);
1020  $fields = array_flip(array_flip(array_filter($fields)));
1021  $fieldsI18n = $fields;
1022  array_walk($fieldsI18n, create_function('&$v', '$v = "'.$i18nTableName.'_".$v;'));
1023  array_walk($fields, create_function('&$v', '$v = "'.$i18nTableName.'.".$v." AS '
1024  .$p['table'].'_'.db::getCfg('i18n').'".$v;'));
1025  if (!empty($fields))
1026  $prm['fields'].= ','.implode(',', $fields);
1027  }
1028 
1029  $tmpTables['relatedTable'][$f] = array(
1030  'ident'=>$this->getIdent(),
1031  'tableName'=>$p['table'],
1032  'tableLink'=>$fieldsTableLink,
1033  'table'=>array_merge($fieldsT, array(
1034  'field'=>$p['fk2']['name'],
1035  'sep'=>$p['fk2']['link']['sep'],
1036  'ident'=>$p['table'].'_'.$p['fk2']['link']['ident'],
1037  ))
1038  );
1039  }
1040  if ($this->i18nTable) {
1041  $i18nName = $this->i18nTable->getName();
1042  $primary = $this->i18nTable->getPrimary();
1043  $prm['join'][] = array(
1044  'table'=>$i18nName,
1045  'dir'=>'left outer',
1046  'on'=>$this->rawName.'.'.$this->getIdent().'='.$i18nName.'.'.$primary[0]
1047  );
1048 
1049  // related Table fields
1050  $fields = array($primary[1]);
1051  foreach($this->getI18nFields() as $f) {
1052  $fields[] = $f['name'];
1053  }
1054  $fieldsTableLink = $fields;
1055  array_walk($fieldsTableLink, create_function('&$v', '$v = "'.$i18nName.'_".$v;'));
1056  array_walk($fields, create_function('&$v', '$v = "'.$i18nName.'.".$v." AS '.$i18nName.'_".$v;'));
1057 
1058  if (!empty($fields))
1059  $prm['fields'].= ','.implode(',', $fields);
1060 
1061  // related Table fields
1062  $tmpTables['relatedTable'][$i18nName] = array(
1063  'ident'=>$this->getIdent(),
1064  'tableName'=>$i18nName,
1065  'tableLink'=>$fieldsTableLink,
1066  'table'=>array(
1067  'field'=>$i18nName.'_'.$primary[0],
1068  'sep'=>null,
1069  'ident'=>$i18nName.'_'.$primary[1],
1070  )
1071  );
1072  }
1073  if (array_key_exists('nb', $prm)) {
1074  $tmpTables['nb'] = $prm['nb'];
1075  $tmpTables['st'] = array_key_exists('start', $prm)? $prm['start'] : 0;
1076  unset($prm['nb']);
1077  }
1078  }
1079 
1080  $prm['join'] = array_merge($prm['join'], $join);
1081 
1082  return $prm;
1083  }
1084 
1091  public static function parseLinked(array &$data, array $linked) {
1092  if (!empty($linked) && !empty($data)) {
1093  if (array_key_exists('relatedTable', $linked)) {
1094  $ident = 'id';
1095 
1096  $tmpRelated = array();
1097  $nb = count($data);
1098 
1099  $ids = array();
1100  $current = 0;
1101  $idRelated = array();
1102 
1103  for($i = 0; $i<$nb; $i++) {
1104  $id = $data[$i][$ident];
1105 
1106  $delete = true;
1107  if (!array_key_exists($id, $ids)) {
1108  // new id
1109  $current = $i;
1110  $ids[$id] = $current;
1111  $data[$current]['related'] = array();
1112  $delete = false;
1113  } else
1114  $current = $ids[$id];
1115  foreach($linked['relatedTable'] as $t=>$r) {
1116  if (!array_key_exists($r['tableName'], $data[$current]['related']))
1117  $data[$current]['related'][$r['tableName']] = array();
1118  if (!$data[$i][$r['table']['ident']]
1119  || (array_key_exists($id, $idRelated)
1120  && array_key_exists($r['tableName'], $idRelated[$id])
1121  && in_array($data[$i][$r['table']['ident']], $idRelated[$id][$r['tableName']])))
1122  // The id was already affected to te current element, skip to the next table
1123  continue;
1124 
1125  $tmp = array();
1126 
1127  $label = array();
1128  foreach($r['table'] as $kk=>$fTab) {
1129  if ($kk != 'sep' && $kk != 'ident' && $kk != db::getCfg('i18n')) {
1130  if (!empty($data[$i][$fTab]))
1131  $label[] = $data[$i][$fTab];
1132  if ($fTab != $r['table']['ident'])
1133  unset($data[$i][$fTab]);
1134  }
1135  }
1136  if (!empty($label)) {
1137  $tmp[substr($r['table']['ident'], strlen($r['tableName'])+1)] = $data[$i][$r['table']['ident']];
1138  $tmp[$r['table']['field']] = implode($r['table']['sep'], $label);
1139  }
1140  $idRelated[$id][$r['tableName']][] = $data[$i][$r['table']['ident']];
1141 
1142  foreach($r['tableLink'] as $tl) {
1143  $tmp[substr($tl, strlen($t)+1)] = $data[$i][$tl];
1144  unset($data[$i][$tl]);
1145  }
1146 
1147  if (!empty($tmp)) {
1148  $data[$current]['related'][$r['tableName']][] = $tmp;
1149  }
1150  }
1151  // Delete the duplicate
1152  if ($delete)
1153  unset($data[$i]);
1154  }
1155  $data = array_merge($data);
1156 
1157  unset($linked['relatedTable']);
1158 
1159  if (array_key_exists('nb', $linked)) {
1160  $data = array_slice($data, $linked['st'], $linked['nb']);
1161  unset($linked['nb']);
1162  unset($linked['st']);
1163  }
1164  }
1165 
1166  $linkedKey = db::getCfg('linked');
1167  array_walk($data, create_function('&$v, $i, &$tl', '
1168  $v["'.$linkedKey.'"] = array();
1169  foreach($tl as $k=>$t) {
1170  $v["'.$linkedKey.'"][$k] = array();
1171  $label = array();
1172  $length = strlen($k)+1;
1173  foreach($t as $kk=>$f) {
1174  if ($kk != "sep" && $kk != "ident") {
1175  if (!empty($v[$f]))
1176  $label[] = $v[$f];
1177  $v["'.$linkedKey.'"][$k][substr($f, $length)] = $v[$f];
1178  if ($f != $t["ident"])
1179  unset($v[$f]);
1180  }
1181  }
1182  if (array_key_exists($t["ident"], $v) && $v[$t["ident"]]) {
1183  $ident = substr($t["ident"], $length);
1184  $v["'.$linkedKey.'"][$k][$ident] = $v[$t["ident"]];
1185  $v[$k] = $v["'.$linkedKey.'"][$k]["label"] = implode($t["sep"], $label);
1186  } else {
1187  $v[$k] = null;
1188  $v["'.$linkedKey.'"][$k] = array();
1189  }
1190  }
1191  '), $linked);
1192  }
1193  }
1194 
1201  public function find($where) {
1202  return $this->select(array(
1203  'where'=>$where,
1204  'first'=>true
1205  ));
1206  }
1207 
1216  public function findText($text, $filter = null) {
1217  if (!$filter) {
1218  $filter = array();
1219  foreach($this->fields as &$f)
1220  if ($f['text'])
1221  $filter[] = $f['name'];
1222  } else if (!is_array($filter))
1223  $filter = explode(',', $filter);
1224 
1225  $where = $this->getWhere(array('op'=>'OR'));
1226  foreach($filter as $f)
1227  $where->add(array(
1228  'field'=>$this->getRawName().'.'.$f,
1229  'val'=>'%'.$text.'%',
1230  'op'=>'LIKE'
1231  ));
1232 
1233  $prm = array(
1234  'whereOp'=>'OR',
1235  'where'=>$where,
1236  );
1237  return $this->select($prm);
1238  }
1239 
1246  public function getRange($field = null) {
1247  if (is_null($field))
1248  $field = $this->getIdent();
1249  $query = 'SELECT MIN('.$field.'),MAX('.$field.') FROM '.$this->getRawName()
1250  .' WHERE '.$this->cfg->whereRange;
1251  $tmp = $this->getDb()->query($query)->fetchAll(PDO::FETCH_NUM);
1252  $tmp = $tmp[0];
1253  $min = array_key_exists(0, $tmp) ? $tmp[0] : 0;
1254  return array(
1255  'min'=>$min,
1256  'max'=>array_key_exists(1, $tmp) ? $tmp[1] : $min,
1257  );
1258  }
1259 
1266  public function clearCache($clearTargeting = null) {
1267  if (is_null($clearTargeting))
1268  $clearTargeting = $this->cfg->cacheClearTargeting;
1269  if ($clearTargeting) {
1270  foreach($this->getTargetingTables() as $tbl) {
1271  db::get('table', $tbl)->clearCache(false);
1272  }
1273  }
1274  if (!$this->cfg->cacheEnabled)
1275  return false;
1276  return $this->getDb()->getCache()->delete(array(
1277  'callFrom'=>'db_table-select',
1278  'type'=>'get',
1279  'id'=>$this->getName().'-*'
1280  ));
1281  }
1282 
1291  public function getRow(array $data = array(), $withAuto = false, array $morePrm = array()) {
1292  $cols = array_flip($this->cols);
1293  $data = array_intersect_key($data, $cols);
1294 
1295  foreach($this->fields as &$f) {
1296  if ((!$f['auto'] || $withAuto) && !array_key_exists($f['name'], $data))
1297  $data[$f['name']] = $f['default'];
1298  }
1299 
1300  $prm = array_merge($morePrm, array(
1301  'db'=>$this->getDb(),
1302  'data'=>$data
1303  ));
1304  if (array_key_exists($this->getIdent(), $data) && $data[$this->getIdent()])
1305  $prm['findId'] = $data[$this->getIdent()];
1306  return db::get('row', $this, $prm);
1307  }
1308 
1309 }
static get($get=null)
static htmlOut($val, $key=false)
getLinkedTableRow($field, array $data=array())
getRelated($name=null)
isRelated($name)
dateAutoData(array &$data, $type)
getLabel($field=null)
getLinkedTableName($tablename)
isLinked($field)
select(array $prm=array())
getLinked($field=null)
getLinkedTable($field)
insert(array $data)
static parseLinked(array &$data, array $linked)
dateValue($type)
getRelatedTableName($name, $add=true)
isTargeting($tableName)
static initTab(array &$vars, array $init)
selectQuery(array $prm, &$tmpTables)
_initLinkedTables()
count(array $prm)
getRange($field=null)
static getCfg($key)
Definition: db.class.php:125
getRow(array $data=array(), $withAuto=false, array $morePrm=array())
clearCache($clearTargeting=null)
getI18nLabel($field=null)
find($where)
getTargetingTables()
findText($text, $filter=null)
static unI18nName($field)
Definition: db.class.php:145
getRelatedTable($name)
static isI18nName($field)
Definition: db.class.php:135
static mergeCfg(array &$prm, array $cfg)
update(array $data, $where=null)
replace(array $data)
static get($type, $table, array $prm=array())
Definition: db.class.php:87
getField($field=null, $keyVal=null)
getWhere(array $prm=array())
$f
Definition: list.php:6
_initRelatedTables()
getRelatedTableRow($name, array $data=array())
Generated on Sun Oct 15 2017 22:25:20 for nyroFwk by doxygen 1.8.13