LazyRecord\BaseModel::create PHP Method

create() public method

1. create method calls beforeCreate to trigger events or filter arguments. 2. it runs filterArrayWithColumns method to filter arguments with column definitions. 3. use currentUserCan method to check permission. 4. get column definitions and run filters, default value builders, canonicalizer, type constraint checkers to build a new arguments. 5. use these new arguments to build a SQL query with SQLBuilder\QueryBuilder. 6. insert SQL into data source (write) 7. reutrn the operation result.
public create ( array $args, array $options = [] ) : Result
$args array data
$options array
return Result operation result (success or error)
    public function create(array $args, array $options = array())
    {
        if (empty($args) || $args === null) {
            return $this->reportError('Empty arguments');
        }
        $validationResults = array();
        $validationError = false;
        $schema = $this->getSchema();
        // save $args for afterCreate trigger method
        $origArgs = $args;
        $k = static::PRIMARY_KEY;
        $sql = $vars = null;
        $this->_data = array();
        $stm = null;
        static $cacheable;
        $cacheable = extension_loaded('xarray');
        $conn = $this->getWriteConnection();
        $driver = $this->getWriteQueryDriver();
        // Just a note: Exceptions should be used for exceptional conditions; things you
        // don't expect to happen. Validating input isn't very exceptional.
        $args = $this->beforeCreate($args);
        if ($args === false) {
            return $this->reportError(_('Create failed'), array('args' => $args));
        }
        // first, filter the array, arguments for inserting data.
        $args = array_intersect_key($args, array_flip($schema->columnNames));
        // @codegenBlock currentUserCan
        if (!$this->currentUserCan($this->getCurrentUser(), 'create', $args)) {
            return $this->reportError(_('Permission denied. Can not create record.'), array('args' => $args));
        }
        // @codegenBlockEnd
        // arguments that are will Bind
        $insertArgs = array();
        foreach ($schema->columns as $n => $c) {
            // if column is required (can not be empty)
            //   and default is defined.
            if (!$c->primary && (!isset($args[$n]) || !$args[$n])) {
                if ($val = $c->getDefaultValue($this, $args)) {
                    $args[$n] = $val;
                }
            }
            // if type constraint is on, check type,
            // if not, we should try to cast the type of value,
            // if type casting is fail, we should throw an exception.
            // short alias for argument value.
            $val = isset($args[$n]) ? $args[$n] : null;
            // if column is required (can not be empty) //   and default is defined.
            // @codegenBlock validateRequire
            if ($c->required && array_key_exists($n, $args) && $args[$n] === null) {
                return $this->reportError("Value of {$n} is required.");
            }
            // @codegenBlockEnd
            // @codegenBlock typeConstraint
            if ($c->typeConstraint && ($val !== null && !is_array($val) && !$val instanceof Raw)) {
                if (false === $c->checkTypeConstraint($val)) {
                    return $this->reportError("{$val} is not " . $c->isa . ' type');
                }
            } elseif ($val !== null && !is_array($val) && !$val instanceof Raw) {
                $val = $c->typeCasting($val);
            }
            // @codegenBlockEnd
            // @codegenBlock filterColumn
            if ($c->filter || $c->canonicalizer) {
                $val = $c->canonicalizeValue($val, $this, $args);
            }
            // @codegenBlockEnd
            // @codegenBlock validateColumn
            if ($validationResult = $this->_validateColumn($c, $val, $args)) {
                $validationResults[$n] = $validationResult;
                if (!$validationResult['valid']) {
                    $validationError = true;
                }
            }
            // @codegenBlockEnd
            if ($val !== null) {
                // Update filtered value back to args
                // Note that we don't deflate a scalar value, this is to prevent the overhead of data reload from database
                // We should try to keep all variables just like the row result we query from database.
                if (is_object($val) || is_array($val)) {
                    $args[$n] = $c->deflate($val, $driver);
                } else {
                    $args[$n] = $val;
                }
                if (is_scalar($val) || is_null($val)) {
                    $insertArgs[$n] = new Bind($n, $driver->cast($val));
                } elseif ($val instanceof Raw) {
                    $insertArgs[$n] = $val;
                    $cacheable = false;
                } else {
                    // deflate objects into string
                    $insertArgs[$n] = new Bind($n, $c->deflate($val, $driver));
                }
            }
        }
        // @codegenBlock handleValidationError
        if ($validationError) {
            return $this->reportError('Validation failed.', array('validations' => $validationResults));
        }
        // @codegenBlockEnd
        $arguments = new ArgumentArray();
        $cacheKey = null;
        if ($cacheable) {
            $cacheKey = array_keys_join($insertArgs);
            if (isset($this->_preparedCreateStms[$cacheKey])) {
                $stm = $this->_preparedCreateStms[$cacheKey];
                foreach ($insertArgs as $name => $bind) {
                    $arguments->bind($bind);
                }
            }
        }
        if (!$stm) {
            $query = new InsertQuery();
            $query->into($this->table);
            $query->insert($insertArgs);
            $query->returning($k);
            $sql = $query->toSql($driver, $arguments);
            $stm = $conn->prepare($sql);
            if ($cacheable) {
                $this->_preparedCreateStms[$cacheKey] = $stm;
            }
        }
        if (false === $stm->execute($arguments->toArray())) {
            return $this->reportError('Record create failed.', array('validations' => $validationResults, 'args' => $args, 'sql' => $sql));
        }
        $pkId = null;
        if ($driver instanceof PDOPgSQLDriver) {
            $this->_data[$k] = $args[$k] = $pkId = intval($stm->fetchColumn());
        } else {
            $this->_data[$k] = $args[$k] = $pkId = intval($conn->lastInsertId());
        }
        if ($pkId && (isset($options['reload']) && $options['reload'] || $this->autoReload)) {
            $this->load($pkId);
        } else {
            $this->_data = $args;
        }
        $this->afterCreate($origArgs);
        $stm->closeCursor();
        // collect debug info
        return $this->reportSuccess('Record created.', array('id' => $pkId, 'sql' => $sql, 'args' => $args, 'binds' => $arguments, 'validations' => $validationResults, 'type' => Result::TYPE_CREATE));
    }

Usage Example

Beispiel #1
0
 /**
  * array fgetcsv ( resource $handle [, int $length = 0 [, string $delimiter = "," [, string $enclosure = '"' [, string $escape = "\" ]]]] ).
  */
 public function importResource($fd, $unsetPrimaryKey = false)
 {
     $schema = $this->model->getSchema();
     if ($this->columnMap) {
         $columnNames = $this->columnMap;
     } else {
         $columnNames = fgetcsv($fd);
     }
     while (($fields = fgetcsv($fd)) !== false) {
         $args = array();
         foreach ($columnNames as $idx => $columnName) {
             $columnValue = $fields[$idx];
             $args[$columnName] = $columnValue;
         }
         if ($unsetPrimaryKey) {
             if ($pk = $schema->primaryKey) {
                 unset($args[$pk]);
             }
         }
         $ret = $this->model->create($args);
     }
 }