Beispiel #1
2
 /**
  * @inheritdoc
  */
 public function rules()
 {
     return array_merge(parent::rules(), [[['loginModelClass', 'controllerClass', 'viewPath'], 'filter', 'filter' => 'trim'], [['loginModelClass', 'controllerClass', 'viewPath'], 'required'], [['loginModelClass'], 'match', 'pattern' => '/^[\\w\\\\]*$/', 'message' => 'Only word characters and backslashes are allowed.'], [['loginModelClass'], 'validateClass', 'params' => ['extends' => Model::className()]], [['baseControllerClass'], 'validateClass', 'params' => ['extends' => Controller::className()]], [['controllerClass'], 'match', 'pattern' => '/Controller$/', 'message' => 'Controller class name must be suffixed with "Controller".'], [['controllerClass'], 'match', 'pattern' => '/(^|\\\\)[A-Z][^\\\\]+Controller$/', 'message' => 'Controller class name must start with an uppercase letter.'], [['controllerClass'], 'validateNewClass'], [['viewPath'], 'match', 'pattern' => '/^@?\\w+[\\-\\/\\w]*$/', 'message' => 'Only word characters, dashes, slashes and @ are allowed.'], [['viewPath'], 'validatePath'], [['enableI18N'], 'boolean'], [['messageCategory'], 'validateMessageCategory', 'skipOnEmpty' => false]]);
 }
Beispiel #2
0
 /**
  * Initializes CRUD handler
  * @throws \yii\base\ErrorException
  */
 public function __construct()
 {
     $class = $this->modelClass();
     if (!is_subclass_of($class, \yii\base\Model::className())) {
         throw new \yii\base\ErrorException('Invalid model class. Method "getModelClass" has to retrieve Model descendant class.');
     }
 }
 /**
  * @param \yii\base\Model $model
  *
  * @return string
  */
 public function getModelDirectory(Model $model)
 {
     if (!$model->canGetProperty('idAttribute')) {
         throw new \LogicException("Model {$model->className()} has not 'idAttribute' property");
     }
     $modelName = $this->getShortClass($model);
     /** @noinspection PhpUndefinedFieldInspection */
     $modelId = $model->{$model->idAttribute};
     return $this->_getSubDirectory($modelName, $modelId);
 }
Beispiel #4
0
 /**
  * @inheritdoc
  */
 public function rules()
 {
     return array_merge(parent::rules(), [[['modelClass', 'formModelClass', 'baseClass', 'controllerClass', 'baseControllerClass'], 'filter', 'filter' => 'trim'], [['searchModelClass'], 'compare', 'compareAttribute' => 'modelClass', 'operator' => '!==', 'message' => 'Search Model Class must not be equal to Model Class.'], [['baseClass'], 'required'], [['modelClass', 'modelClass', 'controllerClass', 'baseControllerClass', 'searchModelClass'], 'match', 'pattern' => '/^[\\w\\\\]*$/', 'message' => 'Only word characters are allowed.'], [['baseClass'], 'match', 'pattern' => '/^[\\w\\\\]+$/', 'message' => 'Only word characters and backslashes are allowed.'], [['controllerClass', 'searchModelClass'], 'validateNewClass'], [['modelClass', 'formModelClass'], 'validateModelClass', 'skipOnEmpty' => false], [['baseClass', 'modelClass'], 'validateClass', 'params' => ['extends' => Model::className()]], [['baseControllerClass'], 'validateClass', 'params' => ['extends' => Controller::className()]], [['controllerClass'], function ($field) {
         if ($this->{$field}) {
             if (!$this->formModelClass) {
                 $this->addError('formModelClass', 'formModelClass required');
             }
             if (!$this->searchModelClass) {
                 $this->addError('searchModelClass', 'searchModelClass required');
             }
         }
     }]]);
 }
Beispiel #5
0
 /**
  * Creating model using $model configuration property
  * @return bool true, if model was created, false if it has been already configured as object
  * @throws \yii\base\InvalidConfigException
  */
 protected function createModel()
 {
     if ($this->model instanceof \yii\base\Model) {
         Yii::info('Model already configured as instanceof ' . $this->model->className(), __METHOD__);
         return false;
     }
     if (is_array($this->model)) {
         if (!ArrayHelper::isIndexed($this->model) || !$this->model[0] instanceof \yii\base\Model) {
             throw new InvalidConfigException("Property 'model'" . ' must be configured as indexed array of \\yii\\base\\Model');
         }
         Yii::info('Model property configured as array of ' . $this->model[0]->className(), __METHOD__);
         return false;
     }
     if (is_string($this->model)) {
         $this->model = Yii::createObject($configuration = ['class' => $this->model]);
         Yii::info('Model initialized with configuration: ' . VarDumper::dumpAsString($configuration), __METHOD__);
     }
     return true;
 }
 /**
  * @inheritdoc
  */
 public function rules()
 {
     return array_merge(parent::rules(), [[['modelClass', 'viewName', 'scenarioName', 'viewPath'], 'filter', 'filter' => 'trim'], [['modelClass', 'viewName', 'viewPath'], 'required'], [['modelClass'], 'match', 'pattern' => '/^[\\w\\\\]*$/', 'message' => 'Only word characters and backslashes are allowed.'], [['modelClass'], 'validateClass', 'params' => ['extends' => Model::className()]], [['viewName'], 'match', 'pattern' => '/^\\w+[\\-\\/\\w]*$/', 'message' => 'Only word characters, dashes and slashes are allowed.'], [['viewPath'], 'match', 'pattern' => '/^@?\\w+[\\-\\/\\w]*$/', 'message' => 'Only word characters, dashes, slashes and @ are allowed.'], [['viewPath'], 'validateViewPath'], [['scenarioName'], 'match', 'pattern' => '/^[\\w\\-]+$/', 'message' => 'Only word characters and dashes are allowed.'], [['enableI18N'], 'boolean'], [['messageCategory'], 'validateMessageCategory', 'skipOnEmpty' => false]]);
 }
Beispiel #7
0
 /**
  * @inheritdoc
  */
 public function validateAttribute($model, $attribute)
 {
     if (!$model instanceof ContainerInterface) {
         throw new InvalidConfigException('Owner model must implement "yii2tech\\embedded\\ContainerInterface" interface.');
     }
     $mapping = $model->getEmbeddedMapping($attribute);
     if ($this->initializedOnly && !$mapping->getIsValueInitialized()) {
         return;
     }
     $embedded = $model->getEmbedded($attribute);
     if ($mapping->multiple) {
         if (!is_array($embedded) && !$embedded instanceof \IteratorAggregate) {
             $error = $this->message;
         } else {
             foreach ($embedded as $embeddedModel) {
                 if (!$embeddedModel instanceof Model) {
                     throw new InvalidConfigException('Embedded object "' . get_class($embeddedModel) . '" must be an instance or descendant of "' . Model::className() . '".');
                 }
                 if (!$embeddedModel->validate()) {
                     $error = $this->message;
                 }
             }
         }
     } else {
         if (!$embedded instanceof Model) {
             throw new InvalidConfigException('Embedded object "' . get_class($embedded) . '" must be an instance or descendant of "' . Model::className() . '".');
         }
         if (!$embedded->validate()) {
             $error = $this->message;
         }
     }
     if (!empty($error)) {
         $this->addError($model, $this->addErrorToSource ? $mapping->source : $attribute, $error);
     }
 }
 public function init()
 {
     parent::init();
     echo \yii\helpers\Html::hiddenInput("sx-model-value", $this->modelWithProperties->id);
     echo \yii\helpers\Html::hiddenInput("sx-model", $this->modelWithProperties->className());
 }
 /**
  * Returns the JavaScript needed for performing client-side validation.
  *
  * @param \yii\base\Model $baseModel the data model being validated
  * @param string $attribute the name of the attribute to be validated.
  * @param \yii\web\View $view the view object that is going to be used to render views or view files
  * containing a model form with this validator applied.
  * @return string the client-side validation script. Null if the validator does not support
  * client-side validation.
  * @see \yii\widgets\ActiveForm::enableClientValidation
  */
 public function clientValidateAttribute($baseModel, $attribute, $view)
 {
     $class = $this->baseModel;
     /** @var ActiveRecord|Model $model */
     $model = new $class();
     /** @var Validator[] $activeValidators */
     $activeValidators = $model->getActiveValidators();
     $clientValidators = [];
     foreach ($activeValidators as $_next) {
         foreach ($_next->attributes as $_attribute) {
             if (!(isset($clientValidators[$_attribute]) && is_array($clientValidators[$_attribute]))) {
                 $clientValidators[$_attribute] = [];
             }
             $clientValidators[$_attribute][$_next->className()] = new JsExpression('function (attribute, value, messages, options, deffered, $form) {' . preg_replace('/;$/', '', $_next->clientValidateAttribute($model, $attribute, $view)) . '}');
         }
     }
     $options = ['message' => \Yii::$app->getI18n()->format($this->message, ['attribute' => $model->getAttributeLabel($attribute)], \Yii::$app->language)];
     if ($this->skipOnEmpty) {
         $options['skipOnEmpty'] = 1;
     }
     $options['validatorList'] = $clientValidators;
     $modelName = explode("\\", $baseModel->className());
     $options['modelName'] = $modelName[sizeof($modelName) - 1];
     $modelName = explode("\\", $this->baseModel);
     $options['modelBase'] = $modelName[sizeof($modelName) - 1];
     $options['attribute'] = $attribute;
     MultipleModelValidatorAssets::register($view);
     $str = 'yii.validation.multipleModel(attribute, value, messages, ' . Json::encode($options) . ", deferred, \$form);";
     return $str;
 }
Beispiel #10
0
 /**
  * @inheritdoc
  */
 public function rules()
 {
     return array_merge(parent::rules(), [[['moduleID', 'controllerID', 'actions', 'formActions', 'baseControllerClass'], 'filter', 'filter' => 'trim'], [['controllerID', 'baseControllerClass'], 'required'], [['controllerID'], 'match', 'pattern' => '/^[a-z][a-z0-9\\-\\/]*$/', 'message' => 'Only a-z, 0-9, dashes (-) and slashes (/) are allowed.'], [['actions', 'formActions'], 'match', 'pattern' => '/^[a-z][a-z0-9\\-,\\s]*$/', 'message' => 'Only a-z, 0-9, dashes (-), spaces and commas are allowed.'], [['baseControllerClass', 'modelClass'], 'match', 'pattern' => '/^[\\w\\\\]*$/', 'message' => 'Only word characters and backslashes are allowed.'], [['baseControllerClass'], 'validateClass', 'params' => ['extends' => Controller::className()]], [['scenarioName'], 'match', 'pattern' => '/^[\\w\\-]+$/', 'message' => 'Only word characters and dashes are allowed.'], [['modelClass'], 'validateClass', 'params' => ['extends' => Model::className()]], [['moduleID'], 'validateModuleID']]);
 }
Beispiel #11
0
 public function init()
 {
     if (!is_subclass_of($this->modelClass, 'common\\models\\SearchModelInterface') && !is_subclass_of($this->modelClass, Model::className())) {
         throw new InvalidConfigException("Property 'modelClass': given class must implement 'common\\models\\SearchModelInterface' and extend '" . Model::className() . "'");
     }
 }
 /**
  * @param \yii\base\Model $model
  */
 public function __construct($model)
 {
     $this->errors = $model->errors;
     parent::__construct('Cannot save model ' . $model->className() . ', errors: ' . print_r($this->errors, true));
 }
Beispiel #13
0
 /**
  * Checks whether the $model exists in the database.
  *
  * @param string $targetClass the name of the ActiveRecord class that should be used to validate the uniqueness
  * of the current attribute value.
  * @param array $conditions conditions, compatible with [[\yii\db\Query::where()|Query::where()]] key-value format.
  * @param Model $model the data model to be validated
  *
  * @return bool whether the model already exists
  */
 private function modelExists($targetClass, $conditions, $model)
 {
     /** @var ActiveRecordInterface $targetClass $query */
     $query = $this->prepareQuery($targetClass, $conditions);
     if (!$model instanceof ActiveRecordInterface || $model->getIsNewRecord() || $model->className() !== $targetClass::className()) {
         // if current $model isn't in the database yet then it's OK just to call exists()
         // also there's no need to run check based on primary keys, when $targetClass is not the same as $model's class
         $exists = $query->exists();
     } else {
         // if current $model is in the database already we can't use exists()
         /** @var $models ActiveRecordInterface[] */
         $models = $query->select($targetClass::primaryKey())->limit(2)->all();
         $n = count($models);
         if ($n === 1) {
             $keys = array_keys($conditions);
             $pks = $targetClass::primaryKey();
             sort($keys);
             sort($pks);
             if ($keys === $pks) {
                 // primary key is modified and not unique
                 $exists = $model->getOldPrimaryKey() != $model->getPrimaryKey();
             } else {
                 // non-primary key, need to exclude the current record based on PK
                 $exists = reset($models)->getPrimaryKey() != $model->getOldPrimaryKey();
             }
         } else {
             $exists = $n > 1;
         }
     }
     return $exists;
 }
Beispiel #14
0
 /**
  * Saves uploaded files.
  * @param boolean $runValidation whether the validation must be called before saving.
  * @param array|null $attributeNames list of file attribute names that need to be saved. Defaults to null,
  * meaning all attributes that are loaded from DB will be saved.
  * @throws InvalidValueException if the behavior has invalid owner or any file cannot be saved.
  */
 public function saveUploadedFiles($runValidation = true, $attributeNames = null)
 {
     if (!($owner = $this->owner) || !$owner instanceof Model) {
         throw new InvalidValueException(get_class($this) . ' must be attached to an instance of ' . Model::className() . '.');
     }
     if ($runValidation) {
         $this->validateFileAttributes($attributeNames);
     }
     $attributeNames = is_array($attributeNames) ? array_fill_keys($attributeNames, true) : null;
     foreach ($this->fileAttributes() as $fileAttribute) {
         if ($attributeNames !== null && !isset($attributeNames[$fileAttribute])) {
             continue;
         }
         $dataAttribute = $this->getFileDataAttribute($fileAttribute);
         $file = $this->getFileAttribute($fileAttribute);
         if ($owner->hasErrors($fileAttribute) || $owner->hasErrors($dataAttribute)) {
             continue;
         }
         if ($file->status !== File::STATUS_UPLOADED_FILE) {
             continue;
         }
         if (!$file->save()) {
             throw new InvalidValueException("Cannot save file '{$file->name}' of the '{$fileAttribute}' attribute.");
         }
     }
 }
 /**
  * Returns a list of fields that can be returned to end users.
  *
  * These are the fields that should be returned by default when a user does not explicitly specify which
  * fields to return for a model. If the user explicitly which fields to return, only the fields declared
  * in this method can be returned. All other fields will be ignored.
  *
  * By default, this method returns [[Model::attributes()]], which are the attributes defined by a model.
  *
  * You may override this method to select which fields can be returned or define new fields based
  * on model attributes.
  *
  * The value returned by this method should be an array of field definitions. The array keys
  * are the field names, and the array values are the corresponding attribute names or callbacks
  * returning field values. If a field name is the same as the corresponding attribute name,
  * you can use the field name without a key.
  *
  * @return array field name => attribute name or definition
  */
 protected function fields()
 {
     if (is_subclass_of($this->modelClass, Model::className())) {
         /** @var Model $model */
         $model = new $this->modelClass();
         return $model->attributes();
     } else {
         return array_keys(get_class_vars($this->modelClass));
     }
 }