Пример #1
0
 /**
  * Get mapper value
  *
  * @param  string
  * @return string
  */
 protected function value($name, $default = null)
 {
     return $this->mapper && $this->mapper->exists($name) ? $this->mapper->get($name) : $this->get($name, $default);
 }
Пример #2
0
 /**
  * Retrieve contents of key
  * @return mixed
  * @param string $key
  * @param bool $raw
  */
 function &get($key, $raw = false)
 {
     // handle virtual fields
     if (isset($this->vFields[$key])) {
         $out = is_callable($this->vFields[$key]) ? call_user_func($this->vFields[$key], $this) : $this->vFields[$key];
         return $out;
     }
     $fields = $this->fieldConf;
     $id = $this->primary;
     if ($key == '_id' && $this->dbsType == 'sql') {
         $key = $id;
     }
     if ($this->whitelist && !in_array($key, $this->whitelist)) {
         $out = null;
         return $out;
     }
     if ($raw) {
         $out = $this->exists($key) ? $this->mapper->{$key} : NULL;
         return $out;
     }
     if (!empty($fields) && isset($fields[$key]) && is_array($fields[$key]) && !array_key_exists($key, $this->fieldsCache)) {
         // load relations
         if (isset($fields[$key]['belongs-to-one'])) {
             // one-to-X, bidirectional, direct way
             if (!$this->exists($key) || is_null($this->mapper->{$key})) {
                 $this->fieldsCache[$key] = null;
             } else {
                 // get config for this field
                 $relConf = $fields[$key]['belongs-to-one'];
                 // fetch related model
                 $rel = $this->getRelFromConf($relConf, $key);
                 // am i part of a result collection?
                 if ($cx = $this->getCollection()) {
                     // does the collection has cached results for this key?
                     if (!$cx->hasRelSet($key)) {
                         // build the cache, find all values of current key
                         $relKeys = array_unique($cx->getAll($key, true));
                         // find related models
                         $crit = array($relConf[1] . ' IN ?', $relKeys);
                         $relSet = $rel->find($this->mergeWithRelFilter($key, $crit), $this->getRelFilterOption($key), $this->_ttl);
                         // cache relSet, sorted by ID
                         $cx->setRelSet($key, $relSet ? $relSet->getBy($relConf[1]) : NULL);
                     }
                     // get a subset of the preloaded set
                     $result = $cx->getSubset($key, (string) $this->get($key, true));
                     $this->fieldsCache[$key] = $result ? $result[0] : NULL;
                 } else {
                     $crit = array($relConf[1] . ' = ?', $this->get($key, true));
                     $crit = $this->mergeWithRelFilter($key, $crit);
                     $this->fieldsCache[$key] = $rel->findone($crit, $this->getRelFilterOption($key), $this->_ttl);
                 }
             }
         } elseif (($type = isset($fields[$key]['has-one'])) || isset($fields[$key]['has-many'])) {
             $type = $type ? 'has-one' : 'has-many';
             $fromConf = $fields[$key][$type];
             if (!is_array($fromConf)) {
                 trigger_error(sprintf(self::E_REL_CONF_INC, $key));
             }
             $rel = $this->getRelInstance($fromConf[0], null, $key, true);
             $relFieldConf = $rel->getFieldConfiguration();
             $relType = key($relFieldConf[$fromConf[1]]);
             // one-to-*, bidirectional, inverse way
             if ($relType == 'belongs-to-one') {
                 $toConf = $relFieldConf[$fromConf[1]]['belongs-to-one'];
                 if (!is_array($toConf)) {
                     $toConf = array($toConf, $id);
                 }
                 if ($toConf[1] != $id && (!$this->exists($toConf[1]) || is_null($this->mapper->get($toConf[1])))) {
                     $this->fieldsCache[$key] = null;
                 } elseif ($cx = $this->getCollection()) {
                     // part of a result set
                     if (!$cx->hasRelSet($key)) {
                         // emit eager loading
                         $relKeys = $cx->getAll($toConf[1], true);
                         $crit = array($fromConf[1] . ' IN ?', $relKeys);
                         $relSet = $rel->find($this->mergeWithRelFilter($key, $crit), $this->getRelFilterOption($key), $this->_ttl);
                         $cx->setRelSet($key, $relSet ? $relSet->getBy($fromConf[1], true) : NULL);
                     }
                     $result = $cx->getSubset($key, array($this->get($toConf[1])));
                     $this->fieldsCache[$key] = $result ? $type == 'has-one' ? $result[0][0] : CortexCollection::factory($result[0]) : NULL;
                 } else {
                     $crit = array($fromConf[1] . ' = ?', $this->get($toConf[1], true));
                     $crit = $this->mergeWithRelFilter($key, $crit);
                     $opt = $this->getRelFilterOption($key);
                     $this->fieldsCache[$key] = $type == 'has-one' ? $rel->findone($crit, $opt, $this->_ttl) : $rel->find($crit, $opt, $this->_ttl) ?: NULL;
                 }
             } elseif ($relType == 'has-many') {
                 $toConf = $relFieldConf[$fromConf[1]]['has-many'];
                 $mmTable = $this->mmTable($fromConf, $key, $toConf);
                 // create mm table mapper
                 if (!$this->get($id, true)) {
                     $this->fieldsCache[$key] = null;
                     return $this->fieldsCache[$key];
                 }
                 $id = $toConf['relPK'];
                 $rel = $this->getRelInstance(null, array('db' => $this->db, 'table' => $mmTable));
                 if ($cx = $this->getCollection()) {
                     if (!$cx->hasRelSet($key)) {
                         // get IDs of all results
                         $relKeys = $cx->getAll($id, true);
                         // get all pivot IDs
                         $mmRes = $rel->find(array($fromConf['relField'] . ' IN ?', $relKeys), null, $this->_ttl);
                         if (!$mmRes) {
                             $cx->setRelSet($key, NULL);
                         } else {
                             $pivotRel = array();
                             $pivotKeys = array();
                             foreach ($mmRes as $model) {
                                 $val = $model->get($key, true);
                                 $pivotRel[(string) $model->get($fromConf['relField'])][] = $val;
                                 $pivotKeys[] = $val;
                             }
                             // cache pivot keys
                             $cx->setRelSet($key . '_pivot', $pivotRel);
                             // preload all rels
                             $pivotKeys = array_unique($pivotKeys);
                             $fRel = $this->getRelInstance($fromConf[0], null, $key, true);
                             $crit = array($toConf['relPK'] . ' IN ?', $pivotKeys);
                             $relSet = $fRel->find($this->mergeWithRelFilter($key, $crit), $this->getRelFilterOption($key), $this->_ttl);
                             $cx->setRelSet($key, $relSet ? $relSet->getBy($id) : NULL);
                             unset($fRel);
                         }
                     }
                     // fetch subset from preloaded rels using cached pivot keys
                     $fkeys = $cx->getSubset($key . '_pivot', array($this->get($id)));
                     $this->fieldsCache[$key] = $fkeys ? CortexCollection::factory($cx->getSubset($key, $fkeys[0])) : NULL;
                 } else {
                     // find foreign keys
                     $results = $rel->find(array($fromConf['relField'] . ' = ?', $this->get($fromConf['relPK'], true)), null, $this->_ttl);
                     if (!$results) {
                         $this->fieldsCache[$key] = NULL;
                     } else {
                         $fkeys = $results->getAll($key, true);
                         // create foreign table mapper
                         unset($rel);
                         $rel = $this->getRelInstance($fromConf[0], null, $key, true);
                         // load foreign models
                         $filter = array($toConf['relPK'] . ' IN ?', $fkeys);
                         $filter = $this->mergeWithRelFilter($key, $filter);
                         $this->fieldsCache[$key] = $rel->find($filter, $this->getRelFilterOption($key), $this->_ttl);
                     }
                 }
             }
         } elseif (isset($fields[$key]['belongs-to-many'])) {
             // many-to-many, unidirectional
             $fields[$key]['type'] = self::DT_JSON;
             $result = !$this->exists($key) ? null : $this->mapper->get($key);
             if ($this->dbsType == 'sql') {
                 $result = json_decode($result, true);
             }
             if (!is_array($result)) {
                 $this->fieldsCache[$key] = $result;
             } else {
                 // create foreign table mapper
                 $relConf = $fields[$key]['belongs-to-many'];
                 $rel = $this->getRelFromConf($relConf, $key);
                 $fkeys = array();
                 foreach ($result as $el) {
                     $fkeys[] = is_int($el) || ctype_digit($el) ? (int) $el : (string) $el;
                 }
                 // if part of a result set
                 if ($cx = $this->getCollection()) {
                     if (!$cx->hasRelSet($key)) {
                         // find all keys
                         $relKeys = $cx->getAll($key, true);
                         if ($this->dbsType == 'sql') {
                             foreach ($relKeys as &$val) {
                                 $val = substr($val, 1, -1);
                                 unset($val);
                             }
                             $relKeys = json_decode('[' . implode(',', $relKeys) . ']');
                         } else {
                             $relKeys = call_user_func_array('array_merge', $relKeys);
                         }
                         // get related models
                         $crit = array($relConf[1] . ' IN ?', array_unique($relKeys));
                         $relSet = $rel->find($this->mergeWithRelFilter($key, $crit), $this->getRelFilterOption($key), $this->_ttl);
                         // cache relSet, sorted by ID
                         $cx->setRelSet($key, $relSet ? $relSet->getBy($relConf[1]) : NULL);
                     }
                     // get a subset of the preloaded set
                     $this->fieldsCache[$key] = CortexCollection::factory($cx->getSubset($key, $fkeys));
                 } else {
                     // load foreign models
                     $filter = array($relConf[1] . ' IN ?', $fkeys);
                     $filter = $this->mergeWithRelFilter($key, $filter);
                     $this->fieldsCache[$key] = $rel->find($filter, $this->getRelFilterOption($key), $this->_ttl);
                 }
             }
         } elseif (isset($fields[$key]['type'])) {
             if ($this->dbsType == 'sql') {
                 if ($fields[$key]['type'] == self::DT_SERIALIZED) {
                     $this->fieldsCache[$key] = unserialize($this->mapper->{$key});
                 } elseif ($fields[$key]['type'] == self::DT_JSON) {
                     $this->fieldsCache[$key] = json_decode($this->mapper->{$key}, true);
                 }
             }
             if ($this->exists($key) && preg_match('/BOOL/i', $fields[$key]['type'])) {
                 $this->fieldsCache[$key] = (bool) $this->mapper->{$key};
             }
         }
     }
     // fetch cached value, if existing
     $val = array_key_exists($key, $this->fieldsCache) ? $this->fieldsCache[$key] : ($this->exists($key) ? $this->mapper->{$key} : null);
     if ($this->dbsType == 'mongo' && $val instanceof \MongoId) {
         // conversion to string makes further processing in template, etc. much easier
         $val = (string) $val;
     }
     // custom getter
     $out = $this->emit('get_' . $key, $val);
     return $out;
 }
Пример #3
0
 /**
  * Get current field value
  * @return mixed
  */
 protected function getValue()
 {
     return $this->cursor ? $this->map && $this->map->exists($this->cursor) ? $this->map->get($this->cursor) : (isset($this->lookup[$this->cursor]) ? $this->lookup[$this->cursor] : null) : null;
 }