Пример #1
0
 /**
  * Assign data to mapper
  *
  * @param  array  $data
  * @return object $this
  */
 public function assign(array $data)
 {
     foreach ($this->mapper ? $data : [] as $key => $value) {
         $this->mapper->set($key, $value);
     }
     return $this;
 }
Пример #2
0
 /**
  * Resolve default filter and assign default value if field not changed
  */
 public function resolveDefaultFilter()
 {
     $app = Base::instance();
     foreach ($this->map ? $this->map->schema() : [] as $field => $schema) {
         if ($schema['pkey'] && PDO::PARAM_INT === $schema['pdo_type']) {
             continue;
         }
         $filters = [];
         $filters['required'] = [!$schema['nullable']];
         if (preg_match('/^(?<type>\\w+)(?:\\((?<length>.+)\\))?/', $schema['type'], $match)) {
             $length = isset($match['length']) ? $match['length'] : null;
             switch ($match['type']) {
                 case 'int':
                 case 'bigint':
                 case 'smallint':
                 case 'tinyint':
                 case 'integer':
                     $filters['maxInt'] = [null, $length];
                     break;
                 case 'decimal':
                 case 'double':
                 case 'float':
                 case 'real':
                     $x = $app->split($length);
                     $base = pow(10, $x[0] - $x[1]) - 1;
                     $precision = (pow(10, $x[1]) - 1) * 1 / pow(10, $x[1]);
                     $max = $base + $precision;
                     $filters['maxFloat'] = [$max, $length];
                     break;
                 case 'enum':
                 case 'set':
                     $filters['choices'] = [$app->split(str_replace(['"', "'"], '', $length)), $schema['nullable']];
                     break;
                 case 'date':
                     $filters['date'] = [$schema['nullable']];
                     break;
                 default:
                     $filters['maxLength'] = [$length, $schema['nullable']];
                     break;
             }
         }
         $this->filters[$field] = $filters;
         if (!$schema['changed'] && (is_null($schema['value']) || '' === $schema['value']) && !(is_null($schema['default']) || '' === $schema['default'])) {
             $this->map->set($field, $schema['default']);
         }
     }
     return $this;
 }
Пример #3
0
 /**
  * Bind value to key
  * @return mixed
  * @param $key string
  * @param $val mixed
  */
 function set($key, $val)
 {
     $fields = $this->fieldConf;
     unset($this->fieldsCache[$key]);
     // pre-process if field config available
     if (!empty($fields) && isset($fields[$key]) && is_array($fields[$key])) {
         // handle relations
         if (isset($fields[$key]['belongs-to-one'])) {
             // one-to-many, one-to-one
             if (is_null($val)) {
                 $val = NULL;
             } elseif (is_object($val) && !($this->dbsType == 'mongo' && $val instanceof \MongoId)) {
                 // fetch fkey from mapper
                 if (!$val instanceof Cortex || $val->dry()) {
                     trigger_error(self::E_INVALID_RELATION_OBJECT);
                 } else {
                     $relConf = $fields[$key]['belongs-to-one'];
                     $rel_field = is_array($relConf) ? $relConf[1] : '_id';
                     $val = $val->get($rel_field, true);
                 }
             } elseif ($this->dbsType == 'mongo' && !$val instanceof \MongoId) {
                 $val = new \MongoId($val);
             }
         } elseif (isset($fields[$key]['has-one'])) {
             $relConf = $fields[$key]['has-one'];
             if (is_null($val)) {
                 $val = $this->get($key);
                 $val->set($relConf[1], NULL);
             } else {
                 if (!$val instanceof Cortex) {
                     $rel = $this->getRelInstance($relConf[0], null, $key);
                     $rel->load(array('_id = ?', $val));
                     $val = $rel;
                 }
                 $val->set($relConf[1], $this->_id);
             }
             $this->saveCsd[$key] = $val;
             return $val;
         } elseif (isset($fields[$key]['belongs-to-many'])) {
             // many-to-many, unidirectional
             $fields[$key]['type'] = self::DT_JSON;
             $relConf = $fields[$key]['belongs-to-many'];
             $rel_field = is_array($relConf) ? $relConf[1] : '_id';
             $val = $this->getForeignKeysArray($val, $rel_field, $key);
         } elseif (isset($fields[$key]['has-many'])) {
             // many-to-many, bidirectional
             $relConf = $fields[$key]['has-many'];
             if ($relConf['hasRel'] == 'has-many') {
                 // custom setter
                 $val = $this->emit('set_' . $key, $val);
                 $val = $this->getForeignKeysArray($val, '_id', $key);
                 $this->saveCsd[$key] = $val;
                 // array of keys
                 return $val;
             } elseif ($relConf['hasRel'] == 'belongs-to-one') {
                 // TODO: many-to-one, bidirectional, inverse way
                 trigger_error("not implemented");
             }
         }
         // convert array content
         if (is_array($val) && $this->dbsType == 'sql') {
             if ($fields[$key]['type'] == self::DT_SERIALIZED) {
                 $val = serialize($val);
             } elseif ($fields[$key]['type'] == self::DT_JSON) {
                 $val = json_encode($val);
             } else {
                 trigger_error(sprintf(self::E_ARRAY_DATATYPE, $key));
             }
         }
         // add nullable polyfill
         if ($val === NULL && ($this->dbsType == 'jig' || $this->dbsType == 'mongo') && array_key_exists('nullable', $fields[$key]) && $fields[$key]['nullable'] === false) {
             trigger_error(sprintf(self::E_NULLABLE_COLLISION, $key));
         }
         // MongoId shorthand
         if ($this->dbsType == 'mongo' && !$val instanceof \MongoId) {
             if ($key == '_id') {
                 $val = new \MongoId($val);
             } elseif (preg_match('/INT/i', $fields[$key]['type']) && !isset($fields[$key]['relType'])) {
                 $val = (int) $val;
             }
         }
         if (preg_match('/BOOL/i', $fields[$key]['type'])) {
             $val = !$val || $val === 'false' ? false : (bool) $val;
             if ($this->dbsType == 'sql') {
                 $val = (int) $val;
             }
         }
     }
     // fluid SQL
     if ($this->fluid && $this->dbsType == 'sql') {
         $schema = new Schema($this->db);
         $table = $schema->alterTable($this->table);
         // add missing field
         if (!in_array($key, $table->getCols())) {
             // determine data type
             if (isset($this->fieldConf[$key]) && isset($this->fieldConf[$key]['type'])) {
                 $type = $this->fieldConf[$key]['type'];
             } elseif (is_int($val)) {
                 $type = $schema::DT_INT;
             } elseif (is_double($val)) {
                 $type = $schema::DT_DOUBLE;
             } elseif (is_float($val)) {
                 $type = $schema::DT_FLOAT;
             } elseif (is_bool($val)) {
                 $type = $schema::DT_BOOLEAN;
             } elseif (date('Y-m-d H:i:s', strtotime($val)) == $val) {
                 $type = $schema::DT_DATETIME;
             } elseif (date('Y-m-d', strtotime($val)) == $val) {
                 $type = $schema::DT_DATE;
             } elseif (\UTF::instance()->strlen($val) <= 255) {
                 $type = $schema::DT_VARCHAR256;
             } else {
                 $type = $schema::DT_TEXT;
             }
             $table->addColumn($key)->type($type);
             $table->build();
             // update mapper fields
             $newField = $table->getCols(true);
             $newField = $newField[$key];
             $refl = new \ReflectionObject($this->mapper);
             $prop = $refl->getProperty('fields');
             $prop->setAccessible(true);
             $fields = $prop->getValue($this->mapper);
             $fields[$key] = $newField + array('value' => NULL, 'changed' => NULL);
             $prop->setValue($this->mapper, $fields);
         }
     }
     // custom setter
     $val = $this->emit('set_' . $key, $val);
     return $this->mapper->set($key, $val);
 }