/**
  * Attach two-way sync needed behaviors for REST action
  * @param ActionEvent $event
  * @return bool
  * @throws NotSupportedException
  */
 public function beforeRestAction(ActionEvent $event)
 {
     /** @var Action $action */
     $action = $event->action;
     Event::on(BaseActiveRecord::className(), BaseActiveRecord::EVENT_INIT, [$this, 'makeModelSyncable'], null, false);
     switch (get_class($action)) {
         case IndexAction::className():
             $action->attachBehavior('indexLatest', IndexLatestBehavior::className());
             break;
         case CreateAction::className():
             // nothing to attach on create for now
             // TODO: check is needed to behave something here
             break;
         case UpdateAction::className():
             $action->attachBehavior('updateConflict', UpdateConflictBehavior::className());
             break;
         default:
             // TODO: implement custom new so called 'TwoWaySync action' stub for future custom actions
             // TODO: and add method attachSyncBehaviors()
             // $action->attachSyncBehaviors();
             //                throw new NotSupportedException("Not implemented yet");
             break;
     }
     return $event->isValid;
 }
 /**
  * @inheritdoc
  */
 public function rules()
 {
     return array_merge(parent::rules(), [[['modelClass', 'controllerClass'], 'filter', 'filter' => 'trim'], [['modelClass', 'controllerClass'], 'required'], [['modelClass', 'controllerClass'], 'match', 'pattern' => '/^[\\w\\\\]*$/', 'message' => 'Only word characters and backslashes are allowed.'], [['modelClass'], 'validateClass', 'params' => ['extends' => BaseActiveRecord::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', function () {
         $dir = Yii::getAlias('@app') . '/' . $this->moduleId . '/controllers';
         if (!file_exists($dir)) {
             mkdir($dir, 0777, true);
         }
     }], [['controllerClass'], 'validateNewClass']]);
 }
Example #3
0
 /**
  * @throws InvalidConfigException
  */
 public function init()
 {
     parent::init();
     if (!$this->redirectUrl) {
         $this->redirectUrl = Url::previous(self::URL_NAME_INDEX_ACTION);
     }
     if (!is_subclass_of($this->modelClass, BaseActiveRecord::className())) {
         throw new InvalidConfigException("Property 'modelClass': given class extend '" . BaseActiveRecord::className() . "'");
     }
 }
Example #4
0
 /**
  * @inheritdoc
  */
 public function rules()
 {
     return array_merge(parent::rules(), [[['db', 'ns', 'tableName', 'modelClass', 'baseClass'], 'filter', 'filter' => 'trim'], [['ns', 'modelLangClass'], 'filter', 'filter' => function ($value) {
         return trim($value, '\\');
     }], [['modelLangClass'], 'filter', 'filter' => function ($value) {
         if ($value !== '' && strpos($value, '\\') === false) {
             return $this->ns . '\\' . $value;
         }
         return $value;
     }], [['db', 'ns', 'tableName', 'baseClass'], 'required'], [['db', 'modelClass'], 'match', 'pattern' => '/^\\w+$/', 'message' => 'Only word characters are allowed.'], [['ns', 'baseClass'], 'match', 'pattern' => '/^[\\w\\\\]+$/', 'message' => 'Only word characters and backslashes are allowed.'], [['tableName'], 'match', 'pattern' => '/^(\\w+\\.)?([\\w\\*]+)$/', 'message' => 'Only word characters, and optionally an asterisk and/or a dot are allowed.'], [['db'], 'validateDb'], [['ns'], 'validateNamespace'], [['tableName'], 'validateTableName'], [['modelClass'], 'validateModelClass', 'skipOnEmpty' => false], [['modelLangClass'], 'validateClass', 'params' => ['extends' => BaseActiveRecord::className()]], [['baseClass'], 'validateClass', 'params' => ['extends' => ActiveRecord::className()]], [['generateRelations', 'generateLabelsFromComments'], 'boolean'], [['modelClassQuery'], 'boolean'], [['enableI18N'], 'boolean'], [['useTablePrefix'], 'boolean'], [['isLang'], 'boolean'], [['messageCategory'], 'validateMessageCategory', 'skipOnEmpty' => false]]);
 }
Example #5
0
 /**
  * @inheritdoc
  */
 public function rules()
 {
     return array_merge(parent::rules(), [
         [['controllerClass', 'modelClass', 'searchModelClass', 'baseControllerClass'], 'filter', 'filter' => 'trim'],
         [['modelClass', 'controllerClass', 'baseControllerClass', 'indexWidgetType'], 'required'],
         [['searchModelClass'], 'compare', 'compareAttribute' => 'modelClass', 'operator' => '!==', 'message' => 'Search Model Class must not be equal to Model Class.'],
         [['modelClass', 'controllerClass', 'baseControllerClass', 'searchModelClass'], 'match', 'pattern' => '/^[\w\\\\]*$/', 'message' => 'Only word characters and backslashes are allowed.'],
         [['modelClass'], 'validateClass', 'params' => ['extends' => BaseActiveRecord::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', 'searchModelClass'], 'validateNewClass'],
         [['indexWidgetType'], 'in', 'range' => ['grid', 'list']],
         [['modelClass'], 'validateModelClass'],
         [['enableI18N'], 'boolean'],
         [['messageCategory'], 'validateMessageCategory', 'skipOnEmpty' => false],
         ['viewPath', 'safe'],
     ]);
 }
Example #6
0
 /**
  * @inheritdoc
  */
 public function rules()
 {
     return array_merge(\yii\gii\Generator::rules(), [[['moduleID', 'controllerID', 'modelClass', 'searchModelClass', 'baseControllerClass'], 'filter', 'filter' => 'trim'], [['modelClass', 'controllerID', 'baseControllerClass', 'indexWidgetType'], 'required'], [['searchModelClass'], 'compare', 'compareAttribute' => 'modelClass', 'operator' => '!==', 'message' => 'Search Model Class must not be equal to Model Class.'], [['modelClass', 'baseControllerClass', 'searchModelClass'], 'match', 'pattern' => '/^[\\w\\\\]*$/', 'message' => 'Only word characters and backslashes are allowed.'], [['modelClass'], 'validateClass', 'params' => ['extends' => BaseActiveRecord::className()]], [['baseControllerClass'], 'validateClass', 'params' => ['extends' => Controller::className()]], [['controllerID'], 'match', 'pattern' => '/^[a-z][a-z0-9\\-\\/]*$/', 'message' => 'Only a-z, 0-9, dashes (-) and slashes (/) are allowed.'], [['searchModelClass'], 'validateNewClass'], [['controllerClass'], 'filter', 'filter' => function () {
         return $this->getControllerClass();
     }, 'skipOnEmpty' => false], [['indexWidgetType'], 'in', 'range' => ['grid', 'list']], [['modelClass'], 'validateModelClass'], [['moduleID'], 'validateModuleID'], [['enableI18N'], 'boolean'], [['messageCategory'], 'validateMessageCategory', 'skipOnEmpty' => false]]);
 }
 public function testAfterFind()
 {
     /** @var \yii\db\ActiveRecordInterface $customerClass */
     $customerClass = $this->getCustomerClass();
     /** @var BaseActiveRecord $orderClass */
     $orderClass = $this->getOrderClass();
     /** @var TestCase|ActiveRecordTestTrait $this */
     $afterFindCalls = [];
     Event::on(BaseActiveRecord::className(), BaseActiveRecord::EVENT_AFTER_FIND, function ($event) use(&$afterFindCalls) {
         /** @var BaseActiveRecord $ar */
         $ar = $event->sender;
         $afterFindCalls[] = [get_class($ar), $ar->getIsNewRecord(), $ar->getPrimaryKey(), $ar->isRelationPopulated('orders')];
     });
     $customer = $customerClass::findOne(1);
     $this->assertNotNull($customer);
     $this->assertEquals([[$customerClass, false, 1, false]], $afterFindCalls);
     $afterFindCalls = [];
     $customer = $customerClass::find()->where(['id' => 1])->one();
     $this->assertNotNull($customer);
     $this->assertEquals([[$customerClass, false, 1, false]], $afterFindCalls);
     $afterFindCalls = [];
     $customer = $customerClass::find()->where(['id' => 1])->all();
     $this->assertNotNull($customer);
     $this->assertEquals([[$customerClass, false, 1, false]], $afterFindCalls);
     $afterFindCalls = [];
     $customer = $customerClass::find()->where(['id' => 1])->with('orders')->all();
     $this->assertNotNull($customer);
     $this->assertEquals([[$this->getOrderClass(), false, 1, false], [$customerClass, false, 1, true]], $afterFindCalls);
     $afterFindCalls = [];
     if ($this instanceof \yiiunit\extensions\redis\ActiveRecordTest) {
         // TODO redis does not support orderBy() yet
         $customer = $customerClass::find()->where(['id' => [1, 2]])->with('orders')->all();
     } else {
         // orderBy is needed to avoid random test failure
         $customer = $customerClass::find()->where(['id' => [1, 2]])->with('orders')->orderBy('name')->all();
     }
     $this->assertNotNull($customer);
     $this->assertEquals([[$orderClass, false, 1, false], [$orderClass, false, 2, false], [$orderClass, false, 3, false], [$customerClass, false, 1, true], [$customerClass, false, 2, true]], $afterFindCalls);
     $afterFindCalls = [];
     Event::off(BaseActiveRecord::className(), BaseActiveRecord::EVENT_AFTER_FIND);
 }
Example #8
0
 /**
  * @param       $class
  * @param array $attributes
  *
  * @return object
  * @throws Exception
  * @throws \yii\base\InvalidConfigException
  *
  */
 public function createModel($class, $attributes = [])
 {
     /** @var ActiveRecord $model */
     $model = Yii::createObject($class);
     if (!$model || !is_a($model, BaseActiveRecord::className())) {
         throw new Exception('This class is not supported for creating from ArrayObject. Only subclasses of yii\\base\\Model are supported');
     }
     if ($attributes && !empty($attributes)) {
         foreach ($attributes as $attribute) {
             $model->setAttribute($attribute, $this->{$attribute});
         }
     } else {
         $model->setAttributes($this->getValues(), true);
     }
     return $model;
 }
Example #9
0
 public function testAfterFindGet()
 {
     /* @var $customerClass BaseActiveRecord */
     $customerClass = $this->getCustomerClass();
     $afterFindCalls = [];
     Event::on(BaseActiveRecord::className(), BaseActiveRecord::EVENT_AFTER_FIND, function ($event) use(&$afterFindCalls) {
         /* @var $ar BaseActiveRecord */
         $ar = $event->sender;
         $afterFindCalls[] = [get_class($ar), $ar->getIsNewRecord(), $ar->getPrimaryKey(), $ar->isRelationPopulated('orders')];
     });
     $customer = Customer::get(1);
     $this->assertNotNull($customer);
     $this->assertEquals([[$customerClass, false, 1, false]], $afterFindCalls);
     $afterFindCalls = [];
     $customer = Customer::mget([1, 2]);
     $this->assertNotNull($customer);
     $this->assertEquals([[$customerClass, false, 1, false], [$customerClass, false, 2, false]], $afterFindCalls);
     $afterFindCalls = [];
     Event::off(BaseActiveRecord::className(), BaseActiveRecord::EVENT_AFTER_FIND);
 }
Example #10
0
 /**
  * @inheritdoc
  */
 public function rules()
 {
     return array_merge(parent::rules(), [[['modelClass'], 'required'], [['modelClass', 'baseControllerClass', 'extraActions'], 'filter', 'filter' => 'trim'], [['modelClass', 'controllerClass', 'baseControllerClass'], 'match', 'pattern' => '/^[\\w\\\\]*$/', 'message' => 'Only word characters and backslashes are allowed.'], [['modelClass'], 'validateClass', 'params' => ['extends' => BaseActiveRecord::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'], [['modelClass'], 'validateModelClass'], [['controllerActionIndexEnabled', 'controllerActionCreateEnabled', 'controllerActionUpdateEnabled', 'controllerActionDeleteEnabled', 'controllerActionApproveEnabled', 'controllerActionDisapproveEnabled', 'controllerActionDeleteSelectedEnabled', 'controllerActionApproveSelectedEnabled', 'controllerActionDisapproveSelectedEnabled', 'controllerActionDetailViewEnabled'], 'boolean', 'on' => 'controller'], ['headingTitle', 'string', 'on' => 'index'], ['columns', 'safe', 'on' => 'index'], [['toolbarCreateButtonEnabled', 'toolbarApproveButtonEnabled', 'toolbarDisapproveButtonEnabled', 'toolbarDeleteButtonEnabled', 'toolbarRefreshButtonEnabled', 'checkboxColumnEnabled', 'actionColumnEnabled', 'actionApproveEnabled', 'actionDisapproveEnabled', 'idColumnEnabled', 'createdColumnEnabled', 'updatedColumnEnabled', 'detailColumnEnabled', 'pjax', 'condensed', 'hover', 'showPageSummary', 'resizableColumns', 'floatHeader', 'perfectScrollbar', 'toggleData', 'showHeader', 'bootstrap', 'bordered', 'striped'], 'boolean', 'on' => 'index'], ['columns', 'safe', 'on' => 'index'], ['columns', 'safe', 'on' => 'index']]);
 }
Example #11
0
 /**
  * @inheritdoc
  */
 public function rules()
 {
     return [[['template'], 'required', 'message' => 'A code template must be selected.'], [['template'], 'validateTemplate'], [['controllerClass', 'modelClass', 'baseControllerClass', 'baseModelClass'], 'filter', 'filter' => 'trim'], [['modelClass', 'controllerClass', 'baseControllerClass', 'baseModelClass'], 'required'], [['modelClass', 'controllerClass', 'baseControllerClass', 'baseModelClass'], 'match', 'pattern' => '/^[\\w\\\\]*$/', 'message' => 'Only word characters and backslashes are allowed.'], [['baseModelClass'], 'validateClass', 'params' => ['extends' => BaseActiveRecord::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', 'modelClass'], 'validateNewClass'], [['baseModelClass'], 'validateBaseModelClass'], [['enableI18N', 'isImage'], 'boolean'], [['messageCategory'], 'validateMessageCategory', 'skipOnEmpty' => false], ['viewPath', 'safe']];
 }
Example #12
0
 /**
  * @inheritdoc
  */
 public function rules()
 {
     return array_merge(parent::rules(), [[['controllerClass', 'modelClass', 'searchModelClass', 'baseControllerClass'], 'filter', 'filter' => 'trim'], [['modelClass', 'controllerClass', 'baseControllerClass'], 'required'], [['searchModelClass'], 'compare', 'compareAttribute' => 'modelClass', 'operator' => '!==', 'message' => 'Search Model Class 必须继承自 Model Class.'], [['modelClass', 'controllerClass', 'baseControllerClass', 'searchModelClass'], 'match', 'pattern' => '/^[\\w\\\\]*$/', 'message' => '只有字母和"\\"允许使用.'], [['modelClass'], 'validateClass', 'params' => ['extends' => BaseActiveRecord::className()]], [['baseControllerClass'], 'validateClass', 'params' => ['extends' => Controller::className()]], [['controllerClass'], 'match', 'pattern' => '/Controller$/', 'message' => '控制器名字必须以:"Controller".结尾'], [['controllerClass'], 'match', 'pattern' => '/(^|\\\\)[A-Z][^\\\\]+Controller$/', 'message' => '控制器名字必须是大写字母开头.'], [['controllerClass', 'searchModelClass'], 'validateNewClass'], [['modelClass'], 'validateModelClass'], [['enableI18N'], 'boolean'], [['messageCategory'], 'validateMessageCategory', 'skipOnEmpty' => false], ['viewPath', 'safe']]);
 }
 public function init()
 {
     if (!is_a($this->modelClass, BaseActiveRecord::className(), true)) {
         throw new InvalidConfigException('ModelClass must be a subclass off BaseActiveRecord');
     }
 }