Inheritance: implements IteratorAggregat\IteratorAggregate, implements LazyRecord\Schema\ColumnAccessorInterface
Esempio n. 1
0
 /**
  * Run validator to validate column
  *
  * A validator could be:
  *   1. a ValidationKit validator,
  *   2. a closure
  *   3. a function name
  *
  * The validation result must be returned as in following format:
  *
  *   boolean (valid or invalid, true or false)
  *
  *   array( boolean valid , string message )
  *
  *   ValidationKit\ValidationMessage object.
  *
  * This method returns
  *
  *   (object) {
  *       valid: boolean valid or invalid
  *       field: string field name
  *       message: 
  *   }
  */
 protected function _validateColumn(RuntimeColumn $column, $val, array $args)
 {
     // check for requried columns
     if ($column->required && ($val === '' || $val === NULL)) {
         return array('valid' => false, 'message' => sprintf(_('Field %s is required.'), $column->getLabel()), 'field' => $column->name);
     }
     // XXX: migrate this method to runtime column
     if ($validator = $column->validator) {
         if (is_callable($validator)) {
             $ret = call_user_func($validator, $val, $args, $this);
             if (is_bool($ret)) {
                 return array('valid' => $ret, 'message' => 'Validation failed.', 'field' => $column->name);
             } elseif (is_array($ret)) {
                 return array('valid' => $ret[0], 'message' => $ret[1], 'field' => $column->name);
             } else {
                 throw new Exception('Wrong validation result format, Please returns (valid,message) or (valid)');
             }
         } else {
             if (is_string($validator) && is_a($validator, 'ValidationKit\\Validator', true)) {
                 // it's a ValidationKit\Validator
                 $validator = $column->validatorArgs ? new $validator($column->get('validatorArgs')) : new $validator();
                 $ret = $validator->validate($val);
                 $msgs = $validator->getMessages();
                 $msg = isset($msgs[0]) ? $msgs[0] : 'Validation failed.';
                 return array('valid' => $ret, 'message' => $msg, 'field' => $column->name);
             } else {
                 throw new Exception("Unsupported validator");
             }
         }
     }
     if ($val && $column->validValues) {
         if ($validValues = $column->getValidValues($this, $args)) {
             // sort by index
             if (isset($validValues[0]) && !in_array($val, $validValues)) {
                 return array('valid' => false, 'message' => sprintf("%s is not a valid value for %s", $val, $column->name), 'field' => $column->name);
             } else {
                 $values = array_values($validValues);
                 foreach ($values as &$v) {
                     if (is_array($v)) {
                         $v = array_values($v);
                     }
                 }
                 if (!in_array($val, $values)) {
                     return array('valid' => false, 'message' => sprintf(_("%s is not a valid value for %s"), $val, $column->name), 'field' => $column->name);
                 }
             }
         }
     }
 }
Esempio n. 2
0
 /**
  * Translate LazyRecord RuntimeColumn to ActionKit param object.
  *
  * @param RuntimeColumn $column
  * @param BaseModel $record
  * @return Param;
  */
 public static function toParam(RuntimeColumn $column, BaseModel $record = null, Action $action = null)
 {
     $name = $column->name;
     $param = new Param($name, $action);
     if ($column->isa) {
         $param->isa($column->isa);
     }
     // Convert notNull to required
     // required() is basically the same as notNull but provides extra
     // software validation.
     // When creating records, the primary key with auto-increment support is not required.
     // However when updating records, the primary key is required for updating the existing record..
     if ($column->notNull) {
         if ($action && $column->primary) {
             if ($action instanceof CreateRecordAction) {
                 // autoIncrement is not defined, then it requires the input value.
                 if ($column->autoIncrement) {
                     $param->required = false;
                 } else {
                     $param->required = true;
                 }
             } else {
                 if ($action instanceof UpdateRecordAction || $action instanceof DeleteRecordAction) {
                     // primary key column is required to update/delete records.
                     $param->required = true;
                 }
             }
         } else {
             $param->required = true;
         }
     }
     foreach ($column->attributes as $k => $v) {
         // if the model column validator is not compatible with action validator
         if ($k === 'validator' || $v instanceof Raw) {
             continue;
         }
         $param->{$k} = $v;
     }
     // if we got record, load the value from it.
     if ($record) {
         // $val = $record->{$name};
         // $val = $val instanceof BaseModel ? $val->dataKeyValue() : $val;
         $val = $record->getValue($name);
         $param->value = $val;
         // XXX: should get default value (from column definition)
         //      default value is only used in create action.
     } else {
         $default = $column->getDefaultValue();
         if (!$default instanceof Raw) {
             $param->value = $default;
         }
     }
     // convert related collection model to validValues
     if ($param->refer && !$param->validValues) {
         if (class_exists($param->refer, true)) {
             $referClass = $param->refer;
             // it's a `has many`-like relationship
             if (is_subclass_of($referClass, 'LazyRecord\\BaseCollection', true)) {
                 $collection = new $referClass();
                 $options = array();
                 foreach ($collection as $item) {
                     $label = method_exists($item, 'dataLabel') ? $item->dataLabel() : $item->id;
                     $options[$label] = $item->dataKeyValue();
                 }
                 $param->validValues = $options;
             } elseif (is_subclass_of($referClass, 'LazyRecord\\BaseModel', true)) {
                 // it's a `belongs-to`-like relationship
                 $class = $referClass . 'Collection';
                 $collection = new $class();
                 $options = array();
                 foreach ($collection as $item) {
                     $label = method_exists($item, 'dataLabel') ? $item->dataLabel() : $item->id;
                     $options[$label] = $item->dataKeyValue();
                 }
                 $param->validValues = $options;
             } elseif (is_subclass_of($referClass, 'LazyRecord\\Schema\\DeclareSchema', true)) {
                 $schema = new $referClass();
                 $collection = $schema->newCollection();
                 $options = array();
                 foreach ($collection as $item) {
                     $label = method_exists($item, 'dataLabel') ? $item->dataLabel() : $item->id;
                     $options[$label] = $item->dataKeyValue();
                 }
                 $param->validValues = $options;
             } else {
                 throw new Exception('Unsupported refer type');
             }
         } elseif ($relation = $record->getSchema()->getRelation($param->refer)) {
             // so it's a relationship reference
             // TODO: implement this
             throw new Exception('Unsupported refer type');
         }
     }
     //  Convert column type to param type.
     // copy widget attributes
     if ($column->widgetClass) {
         $param->widgetClass = $column->widgetClass;
     }
     if ($column->widgetAttributes) {
         $param->widgetAttributes = $column->widgetAttributes;
     }
     if ($column->immutable) {
         $param->widgetAttributes['readonly'] = 'readonly';
     }
     if ($column->renderAs) {
         $param->renderAs($column->renderAs);
     } elseif ($param->validValues || $param->validPairs || $param->optionValues) {
         $param->renderAs('SelectInput');
     } elseif ($param->name === 'id') {
         $param->renderAs('HiddenInput');
     } else {
         // guess input widget from data type
         $typeMapping = array('date' => 'DateInput', 'datetime' => 'DateTimeInput', 'text' => 'TextareaInput');
         if (isset($typeMapping[$param->type])) {
             $param->renderAs($typeMapping[$param->type]);
         } else {
             $param->renderAs('TextInput');
         }
     }
     return $param;
 }