public function actionEditable()
 {
     if (Yii::$app->request->post('hasEditable') && Yii::$app->request->post('Order')) {
         $posted = Yii::$app->request->post('Order');
         if ($id = Yii::$app->request->post('editableKey')) {
         } else {
             if ($posted['order_id']) {
                 $id = $posted['order_id'];
             }
         }
         $model = $this->findModel($id);
         $this->setSubData();
         if (!ArrayHelper::isAssociative($posted, true)) {
             $post['Order'] = current($posted);
         } else {
             $post['Order'] = $posted;
         }
         $post['Order'] = $this->checkPermission($post['Order']);
         if ($model->load($post) && $model->save()) {
             echo \yii\helpers\Json::encode(['output' => $value, 'message' => '']);
         } else {
             echo \yii\helpers\Json::encode(['output' => '', 'message' => '']);
         }
         return;
     }
 }
예제 #2
0
 public static function findAll($condition = null, $order = null)
 {
     $query = static::find();
     if ($condition == null) {
         if ($order !== null) {
             $query = $query->orderBy($order);
         }
         return $query->all();
     }
     if (ArrayHelper::isAssociative($condition)) {
         // hash condition
         $ret = $query->andWhere($condition);
         if ($order !== null) {
             $ret = $ret->orderBy($order);
         }
         return $ret->all();
     } else {
         // query by primary key(s)
         $primaryKey = static::primaryKey();
         if (isset($primaryKey[0])) {
             $ret = $query->andWhere([$primaryKey[0] => $condition]);
             if ($order !== null) {
                 $ret = $ret->orderBy($order);
             }
             return $ret->all();
         } else {
             throw new InvalidConfigException(get_called_class() . ' must have a primary key.');
         }
     }
 }
예제 #3
0
 public static function findQuery($condition = null, $orderBy = null, $with = null, $params = [])
 {
     $query = static::find();
     if ($with !== null) {
         if (is_string($with)) {
             $query->innerJoinWith($with);
         } else {
             if (isset($with['type'])) {
                 $type = $with['type'];
             }
             if (isset($with[1])) {
                 $type = $with[1];
             } else {
                 $type = 'INNER JOIN';
             }
             $query->joinWith($with[0], true, $type);
         }
     }
     if ($condition !== null && !empty($condition)) {
         if (!ArrayHelper::isAssociative($condition)) {
             // query by primary key
             $primaryKey = static::primaryKey();
             if (isset($primaryKey[0])) {
                 $condition = [$primaryKey[0] => $condition];
             } else {
                 throw new InvalidConfigException('"' . get_called_class() . '" must have a primary key.');
             }
         }
         $query->andWhere($condition);
     }
     if ($orderBy != null) {
         $query->orderBy($orderBy);
     }
     return $query;
 }
예제 #4
0
 /**
  * @inheritdoc
  */
 public static function findAll($condition)
 {
     $query = static::find();
     if (ArrayHelper::isAssociative($condition)) {
         return $query->andWhere($condition)->all();
     } else {
         return static::mget((array) $condition);
     }
 }
예제 #5
0
 /**
  * @param $condition
  *
  * @return mixed
  * @throws InvalidConfigException
  */
 public function identifiedBy($condition)
 {
     /** @var ActiveQuery $this */
     if (!ArrayHelper::isAssociative($condition)) {
         $primaryKey = call_user_func([$this->modelClass, 'primaryKey']);
         if (isset($primaryKey[0])) {
             $condition = [$primaryKey[0] => $condition];
         } else {
             throw new InvalidConfigException('"' . get_called_class() . '" must have a primary key.');
         }
     }
     return $this->andWhere($condition);
 }
 /**
  * Parse a workflow defined as a PHP Array.
  *
  * The workflow definition passed as argument is turned into an array that can be
  * used by the WorkflowFileSource components. 
  * 
  * @param string $wId
  * @param array $definition
  * @param raoul2000\workflow\source\file\WorkflowFileSource $source
  * @return array The parse workflow array definition
  * @throws WorkflowValidationException
  */
 public function parse($wId, $definition, $source)
 {
     if (empty($wId)) {
         throw new WorkflowValidationException("Missing argument : workflow Id");
     }
     if (!\is_array($definition)) {
         throw new WorkflowValidationException("Workflow definition must be provided as an array");
     }
     if (!ArrayHelper::isAssociative($definition)) {
         throw new WorkflowValidationException("Workflow definition must be provided as associative array");
     }
     $initialStatusId = null;
     $normalized = [];
     $startStatusIdIndex = [];
     $endStatusIdIndex = [];
     foreach ($definition as $id => $targetStatusList) {
         list($workflowId, $statusId) = $source->parseStatusId($id, $wId);
         $absoluteStatusId = $workflowId . WorkflowFileSource::SEPARATOR_STATUS_NAME . $statusId;
         if ($workflowId != $wId) {
             throw new WorkflowValidationException('Status must belong to workflow : ' . $absoluteStatusId);
         }
         if (count($normalized) == 0) {
             $initialStatusId = $absoluteStatusId;
             $normalized['initialStatusId'] = $initialStatusId;
             $normalized[WorkflowFileSource::KEY_NODES] = [];
         }
         $startStatusIdIndex[] = $absoluteStatusId;
         $endStatusIds = [];
         if (\is_string($targetStatusList)) {
             $ids = array_map('trim', explode(',', $targetStatusList));
             $endStatusIds = $this->normalizeStatusIds($ids, $wId, $source);
         } elseif (\is_array($targetStatusList)) {
             if (ArrayHelper::isAssociative($targetStatusList, false)) {
                 throw new WorkflowValidationException("Associative array not supported (status : {$absoluteStatusId})");
             }
             $endStatusIds = $this->normalizeStatusIds($targetStatusList, $wId, $source);
         } elseif ($targetStatusList === null) {
             $endStatusIds = [];
         } else {
             throw new WorkflowValidationException('End status list must be an array for status  : ' . $absoluteStatusId);
         }
         if (count($endStatusIds)) {
             $normalized[WorkflowFileSource::KEY_NODES][$absoluteStatusId] = ['transition' => array_fill_keys($endStatusIds, [])];
             $endStatusIdIndex = \array_merge($endStatusIdIndex, $endStatusIds);
         } else {
             $normalized[WorkflowFileSource::KEY_NODES][$absoluteStatusId] = null;
         }
     }
     $this->validate($wId, $source, $initialStatusId, $startStatusIdIndex, $endStatusIdIndex);
     return $normalized;
 }
 /**
  * Finds Entity instance(s) by the given condition.
  * This method is internally called by [[findOne()]] and [[findAll()]].
  * @param mixed $condition please refer to [[findOne()]] for the explanation of this parameter
  * @return ActiveQueryInterface the newly created [[ActiveQueryInterface|ActiveQuery]] instance.
  * @throws InvalidConfigException if there is no primary key defined
  * @internal
  */
 protected function findByCondition($condition)
 {
     $query = $this->find();
     if (!ArrayHelper::isAssociative($condition)) {
         // query by primary key
         $primaryKey = $this->primaryKey();
         if (isset($primaryKey[0])) {
             $condition = [$primaryKey[0] => $condition];
         } else {
             throw new InvalidConfigException('"' . get_called_class() . '" must have a primary key.');
         }
     }
     return $query->andWhere($condition);
 }
 public static function checkAccess($acl, $reference = null)
 {
     // 1) All users
     if (is_null($acl) or $acl == '*') {
         return true;
     }
     // 2) Authenticated users
     if ($acl == '@') {
         return !Yii::$app->user->isGuest;
     }
     $user_id = Yii::$app->user->identity->getId();
     $username = Yii::$app->user->identity->username;
     if (is_array($acl) && ArrayHelper::isAssociative($acl)) {
         if (self::checkAccess('@')) {
             // 3) List of users
             if (array_key_exists('users', $acl) && is_array($acl['users'])) {
                 return in_array($username, $acl['users']);
             } else {
                 // 4) Current user id equals to specified attribute of model
                 $keys = array_keys($acl);
                 $className = array_shift($keys);
                 $attribute = array_shift($acl);
                 if (class_exists($className)) {
                     if (is_null($reference)) {
                         return false;
                     }
                     if ($reference instanceof $className) {
                         return $reference->getAttribute($attribute) == $user_id;
                     } else {
                         try {
                             $whereCondition = [$className::primaryKey()[0] => $reference, $attribute => $user_id];
                             return $className::find()->where($whereCondition)->count() > 0;
                         } catch (Exception $e) {
                             Yii::warning('Invalid configuration: ' . $e->getMessage(), 'file-processor');
                             return false;
                         }
                     }
                 } else {
                     // throw new Exception; // maybe
                     return false;
                 }
             }
         }
     }
     // 5) Defined function
     if (is_callable($acl)) {
         return call_user_func($acl, $reference, $user_id);
     }
     return false;
 }
 /**
  * Formats the specified response.
  * @param Response $response the response to be formatted.
  * @throws \RuntimeException
  */
 public function format($response)
 {
     $response->getHeaders()->set('Content-Type', 'text/csv; charset=UTF-8');
     $handle = fopen('php://temp/maxmemory:' . intval($this->maxMemory), 'w+');
     $response->stream = $handle;
     if ($this->includeColumnNames && $this->checkAllRows) {
         $columns = $this->getColumnNames($response->data);
         if (empty($columns)) {
             return;
         }
         $outputHeader = false;
         $this->put($handle, $columns);
     } else {
         $outputHeader = true;
     }
     if (!$response->data instanceof \Traversable && !is_array($response->data)) {
         throw new \InvalidArgumentException('Response data must be traversable.');
     }
     foreach ($response->data as $row) {
         if ($outputHeader && $this->includeColumnNames && !$this->checkAllRows && \yii\helpers\ArrayHelper::isAssociative($row)) {
             $this->put($handle, array_keys($row));
             $outputHeader = false;
         }
         if ($row instanceof Arrayable) {
             $row = $row->toArray();
         }
         $rowData = [];
         if (isset($columns)) {
             // Map columns.
             foreach ($columns as $column) {
                 if (array_key_exists($column, $row)) {
                     $rowData[] = isset($row[$column]) ? $row[$column] : $this->nullValue;
                 } else {
                     $rowData[] = $this->missingValue;
                 }
             }
         } else {
             foreach ($row as $column => $value) {
                 $rowData[] = isset($value) ? $value : $this->nullValue;
             }
         }
         $this->put($handle, $rowData);
     }
     rewind($handle);
 }
예제 #10
0
 /**
  * @inheritdoc
  */
 public function init()
 {
     Yii::setAlias('@crud-buttons', dirname(__FILE__));
     if (!$this->i18n) {
         $this->i18n = ['class' => 'yii\\i18n\\PhpMessageSource', 'basePath' => '@crud-buttons/messages'];
     }
     Yii::$app->i18n->translations['crud-buttons'] = $this->i18n;
     parent::init();
     if (!$this->actionId) {
         $this->actionId = Yii::$app->controller->action->id;
     }
     $actions = ['index', 'create', 'update', 'delete', 'multi-update', 'multi-delete'];
     if (!$this->actions && $this->actions !== false) {
         $this->actions = array_combine($actions, $actions);
     } elseif ($this->actions && !ArrayHelper::isAssociative($this->actions)) {
         $this->actions = array_combine($this->actions, $this->actions);
     }
 }
예제 #11
0
 /**
  * Get ActiveQuery object
  *
  * @param array $params Condition array
  * @param integer $limit Limit
  * @param integer $page Page
  *
  * @return \yii\redis\ActiveQuery
  */
 public static function getQuery($params = [], $limit = 0, $page = 0)
 {
     $query = static::find();
     if ($params) {
         if (is_array($params)) {
             if (ArrayHelper::isAssociative($params)) {
                 $query = static::findByCondition($params);
             } else {
                 if (ArrayHelper::isAssociative($params, false)) {
                     foreach ($params as $key => $value) {
                         $data = [];
                         $type = 'and';
                         if (is_array($value)) {
                             if (isset($value[0]) && 2 === count($value)) {
                                 $value = [$value[0], $key, $value];
                             }
                             $data = $value;
                             $type = 'or' === $key ? 'or' : $type;
                         } else {
                             $data[$key] = $value;
                         }
                         switch ($type) {
                             case 'and':
                                 $query->andWhere($data);
                                 break;
                             case 'or':
                                 $query->orWhere($data);
                                 break;
                         }
                     }
                 } else {
                     $query = static::findByCondition($params);
                 }
             }
         } else {
             $query = static::findByCondition($params);
         }
     }
     if ((int) $limit) {
         $query->limit((int) $limit)->offset((int) $limit * (int) $page);
     }
     return $query;
 }
예제 #12
0
 /**
  * @param string $name
  *
  * @return mixed|ArrayObject
  */
 public function __get($name)
 {
     $value = ArrayHelper::getValue($this->data, $name, null);
     if (ArrayHelper::isAssociative($value)) {
         return new ArrayObject($value);
     } else {
         if (ArrayHelper::isIndexed($value)) {
             $objects = [];
             foreach ($value as $item) {
                 if (is_array($item)) {
                     $objects[] = new ArrayObject($item);
                 } else {
                     $objects[] = $item;
                 }
             }
             return $objects;
         }
     }
     return $value;
 }
 /**
  * Formats response data in JSON format.
  * @link http://jsonapi.org/format/upcoming/#document-structure
  * @param Response $response
  */
 public function format($response)
 {
     $response->getHeaders()->set('Content-Type', 'application/vnd.api+json; charset=UTF-8');
     if ($response->data !== null) {
         $options = $this->encodeOptions;
         if ($this->prettyPrint) {
             $options |= JSON_PRETTY_PRINT;
         }
         if ($response->isClientError || $response->isServerError) {
             if (ArrayHelper::isAssociative($response->data)) {
                 $response->data = [$response->data];
             }
             $apiDocument = ['errors' => $response->data];
         } elseif (ArrayHelper::keyExists('data', $response->data)) {
             $apiDocument = $response->data;
         } else {
             $apiDocument = ['meta' => $response->data];
         }
         $response->content = Json::encode($apiDocument, $options);
     }
 }
예제 #14
0
 /**
  * Renders the language drop down if there are currently more than one languages in the app.
  * If you pass an associative array of language names along with their code to the URL manager
  * those language names will be displayed in the drop down instead of their codes.
  */
 public function run()
 {
     $languages = isset(Yii::$app->getUrlManager()->languages) ? Yii::$app->getUrlManager()->languages : [];
     if (count($languages) > 1) {
         $items = [];
         $currentUrl = preg_replace('/' . Yii::$app->language . '\\//', '', Yii::$app->getRequest()->getUrl(), 1);
         $isAssociative = ArrayHelper::isAssociative($languages);
         foreach ($languages as $language => $code) {
             $url = $code . $currentUrl;
             if ($isAssociative) {
                 $item = ['label' => $language, 'url' => $url];
             } else {
                 $item = ['label' => $code, 'url' => $url];
             }
             if ($code === Yii::$app->language) {
                 $item['options']['class'] = 'disabled';
             }
             $items[] = $item;
         }
         $this->dropdown['items'] = $items;
         parent::run();
     }
 }
 public function actionEditable()
 {
     if (Yii::$app->request->post('hasEditable') && Yii::$app->request->post('AuthItem')) {
         $posted = Yii::$app->request->post('AuthItem');
         if ($id = Yii::$app->request->post('editableKey')) {
         } else {
             if ($posted['attribute_name']) {
                 $id = $posted['attribute_name'];
             }
         }
         $model = AuthItem::findOne($id);
         if (!ArrayHelper::isAssociative($posted, true)) {
             $post['AuthItem'] = current($posted);
         } else {
             $post['AuthItem'] = $posted;
         }
         if ($model->load($post) && $model->save()) {
             echo \yii\helpers\Json::encode(['output' => Yii::t('order', "Click for edit"), 'message' => '']);
         } else {
             echo \yii\helpers\Json::encode(['output' => Yii::t('order', "Error"), 'message' => '']);
         }
         return;
     }
 }
예제 #16
0
 /**
  * @inheritdoc
  * @return static[]|array an array of ActiveRecord instance, or an empty array if nothing matches.
  */
 public static function findAll($condition)
 {
     $query = static::find();
     if (ArrayHelper::isAssociative($condition)) {
         // hash condition
         return $query->andWhere($condition)->all();
     } else {
         // query by primary key(s)
         $primaryKey = static::primaryKey();
         if (isset($primaryKey[0])) {
             return $query->andWhere([$primaryKey[0] => $condition])->all();
         } else {
             throw new InvalidConfigException(get_called_class() . ' must have a primary key.');
         }
     }
 }
예제 #17
0
 /**
  * Load relational data from owner-model getter.
  *
  * - Create related ActiveRecord objects from POST array data.
  * - Load existing related ActiveRecord objects from database.
  * - Check ON condition format.
  * - Get ActiveQuery object from attribute getter method.
  *
  * Fill $this->relationalData array for each relational attribute:
  *
  * ```php
  * $this->relationalData[$attribute] = [
  *      'newModels' => ActiveRecord[],
  *      'oldModels' => ActiveRecord[],
  *      'activeQuery' => ActiveQuery,
  * ];
  * ```
  *
  * @throws RelationException
  */
 protected function loadData()
 {
     /** @var ActiveQuery $activeQuery */
     foreach ($this->relationalData as $attribute => &$data) {
         $getter = 'get' . ucfirst($attribute);
         $data['activeQuery'] = $activeQuery = $this->owner->{$getter}();
         $data['newModels'] = [];
         $class = $activeQuery->modelClass;
         $notAssociativeArrayOn = !ArrayHelper::isAssociative($activeQuery->on) && !empty($activeQuery->on);
         $notAssociativeArrayViaOn = $activeQuery->multiple && !empty($activeQuery->via) && is_object($activeQuery->via[1]) && !ArrayHelper::isAssociative($activeQuery->via[1]->on) && !empty($activeQuery->via[1]->on);
         if ($notAssociativeArrayOn || $notAssociativeArrayViaOn) {
             Yii::$app->getDb()->getTransaction()->rollBack();
             throw new RelationException('ON condition for attribute ' . $attribute . ' must be associative array');
         }
         $params = !ArrayHelper::isAssociative($activeQuery->on) ? [] : $activeQuery->on;
         if ($activeQuery->multiple) {
             if (empty($activeQuery->via)) {
                 // one-to-many
                 foreach ($activeQuery->link as $childAttribute => $parentAttribute) {
                     $params[$childAttribute] = $this->owner->{$parentAttribute};
                 }
                 if (!empty($data['data'])) {
                     foreach ($data['data'] as $attributes) {
                         $data['newModels'][] = new $class(array_merge($params, ArrayHelper::isAssociative($attributes) ? $attributes : []));
                     }
                 }
             } else {
                 // many-to-many
                 if (!is_object($activeQuery->via[1])) {
                     throw new RelationException('via condition for attribute ' . $attribute . ' cannot must be object');
                 }
                 $via = $activeQuery->via[1];
                 $junctionGetter = 'get' . ucfirst($activeQuery->via[0]);
                 $data['junctionModelClass'] = $junctionModelClass = $via->modelClass;
                 $data['junctionTable'] = $junctionModelClass::tableName();
                 list($data['junctionColumn']) = array_keys($via->link);
                 list($data['relatedColumn']) = array_values($activeQuery->link);
                 $junctionColumn = $data['junctionColumn'];
                 $relatedColumn = $data['relatedColumn'];
                 if (!empty($data['data'])) {
                     // make sure what all model's ids from POST exists in database
                     $countManyToManyModels = $class::find()->where([$class::primaryKey()[0] => $data['data']])->count();
                     if ($countManyToManyModels != count($data['data'])) {
                         throw new RelationException('Related records for attribute ' . $attribute . ' not found');
                     }
                     // create new junction models
                     foreach ($data['data'] as $relatedModelId) {
                         $junctionModel = new $junctionModelClass(array_merge(!ArrayHelper::isAssociative($via->on) ? [] : $via->on, [$junctionColumn => $this->owner->getPrimaryKey()]));
                         $junctionModel->{$relatedColumn} = $relatedModelId;
                         $data['newModels'][] = $junctionModel;
                     }
                 }
                 $data['oldModels'] = $this->owner->{$junctionGetter}()->all();
             }
         } elseif (!empty($data['data'])) {
             // one-to-one
             $data['newModels'][] = new $class($data['data']);
         }
         if (empty($activeQuery->via)) {
             $data['oldModels'] = $activeQuery->all();
         }
         unset($data['data']);
         foreach ($data['newModels'] as $i => $model) {
             $data['newModels'][$i] = $this->replaceExistingModel($model, $attribute);
         }
     }
 }
예제 #18
0
 protected function normalizeEAttributeValue($value)
 {
     if (is_array($value) && ArrayHelper::isAssociative($value, false)) {
         $value = isset($value['value']) ? $value['value'] : null;
     }
     return $value;
 }
예제 #19
0
 /**
  * Load relational data from owner-model getter.
  *
  * - Create related ActiveRecord objects from POST array data.
  * - Load existing related ActiveRecord objects from database.
  * - Check ON condition format.
  * - Get ActiveQuery object from attribute getter method.
  *
  * Fill $this->relationalData array for each relational attribute:
  *
  * ```php
  * $this->relationalData[$attribute] = [
  *      'newModels' => ActiveRecord[],
  *      'oldModels' => ActiveRecord[],
  *      'activeQuery' => ActiveQuery,
  * ];
  * ```
  *
  * @throws Exception
  */
 protected function loadData()
 {
     /** @var ActiveQuery $activeQuery */
     foreach ($this->relationalData as $attribute => &$data) {
         $getter = "get" . ucfirst($attribute);
         $data['activeQuery'] = $activeQuery = $this->owner->{$getter}();
         $data['newModels'] = [];
         $class = $activeQuery->modelClass;
         if (!ArrayHelper::isAssociative($activeQuery->on) && !empty($activeQuery->on)) {
             Yii::$app->getDb()->getTransaction()->rollBack();
             throw new Exception('ON condition for attribute ' . $attribute . ' must be associative array');
         }
         $params = !ArrayHelper::isAssociative($activeQuery->on) ? [] : $activeQuery->on;
         if ($activeQuery->multiple) {
             foreach ($activeQuery->link as $childAttribute => $parentAttribute) {
                 $params[$childAttribute] = $this->owner->{$parentAttribute};
             }
             if (!empty($data['data'])) {
                 foreach ($data['data'] as $attributes) {
                     $data['newModels'][] = new $class(array_merge($params, $attributes));
                 }
             }
         } elseif (!empty($data['data'])) {
             $data['newModels'][] = new $class($data['data']);
         }
         $data['oldModels'] = $activeQuery->all();
         unset($data['data']);
     }
 }
예제 #20
0
 /**
  * @param $fieldMap
  *
  * @return mixed
  * @throws InvalidConfigException
  */
 protected function prepareFieldMap($fieldMap)
 {
     if (ArrayHelper::isIndexed($fieldMap)) {
         return array_combine($fieldMap, $fieldMap);
     }
     if (!ArrayHelper::isAssociative($fieldMap)) {
         throw new InvalidConfigException('Incorrect configuration for fieldMap property');
     }
     return $fieldMap;
 }
예제 #21
0
 /**
  * Finds ActiveRecord instance(s) by the given condition.
  * This method is internally called by [[findOne()]] and [[findAll()]].
  * @param mixed $condition please refer to [[findOne()]] for the explanation of this parameter
  * @param boolean $one whether this method is called by [[findOne()]] or [[findAll()]]
  * @return static|static[]
  * @throws InvalidConfigException if there is no primary key defined
  * @internal
  */
 protected static function findByCondition($condition, $one)
 {
     $query = static::find();
     if (!ArrayHelper::isAssociative($condition)) {
         // query by primary key
         $primaryKey = static::primaryKey();
         if (isset($primaryKey[0])) {
             $condition = [$primaryKey[0] => $condition];
         } else {
             throw new InvalidConfigException(get_called_class() . ' must have a primary key.');
         }
     }
     return $one ? $query->andWhere($condition)->one() : $query->andWhere($condition)->all();
 }
예제 #22
0
 private function relationConfigHelper(&$relations)
 {
     if (!ArrayHelper::isAssociative($relations)) {
         $r2 = [];
         foreach ($relations as $key) {
             $r2[$key] = [];
         }
         $relations = $r2;
     } else {
         foreach ($relations as $key => &$value) {
             if (isset($relations[$key][self::RELATIONS])) {
                 $this->relationConfigHelper($relations[$key][self::RELATIONS]);
             }
         }
     }
 }
예제 #23
0
 /**
  * @inheritdoc
  */
 public function deserialize($wId, $definition, $factory, $model)
 {
     $result = [];
     if (!isset($definition['initialStatusId'])) {
         throw new WorkflowException('Missing "initialStatusId"');
     }
     list($workflowId, $statusId) = $factory->parseWorkflowStatus($definition['initialStatusId'], $wId, $model);
     $initialStatusId = $workflowId . ArrayWorkflowItemFactory::SEPARATOR_STATUS_NAME . $statusId;
     if (!isset($wId)) {
         $wId = $workflowId;
     } elseif ($workflowId != $wId) {
         throw new WorkflowException('Initial status must belong to workflow : ' . $initialStatusId);
     }
     if (!isset($definition[ArrayWorkflowItemFactory::KEY_NODES])) {
         throw new WorkflowException("No status definition found");
     }
     $result['initialStatusId'] = $initialStatusId;
     if (!is_array($definition[ArrayWorkflowItemFactory::KEY_NODES])) {
         throw new WorkflowException('Invalid Status definition : array expected');
     }
     $startStatusIdIndex = [];
     $endStatusIdIndex = [];
     /** @var array $stsDefinitions */
     $stsDefinitions = $definition[ArrayWorkflowItemFactory::KEY_NODES];
     foreach ($stsDefinitions as $key => $value) {
         list($parsedId, $startStatusDef) = $this->parseStatusIdAndDef($key, $value);
         list($workflowId, $statusId) = $factory->parseWorkflowStatus($parsedId, $wId, null);
         $startStatusId = $startStatusIdIndex[] = $workflowId . ArrayWorkflowItemFactory::SEPARATOR_STATUS_NAME . $statusId;
         if ($workflowId != $wId) {
             throw new WorkflowException('Status must belong to workflow : ' . $startStatusId);
         }
         if (is_array($startStatusDef)) {
             if (count($startStatusDef) == 0) {
                 /**
                  * empty status config array
                  *
                  * 'A' => []
                  */
                 $result[ArrayWorkflowItemFactory::KEY_NODES][$startStatusId] = null;
             } else {
                 foreach ($startStatusDef as $startStatusKey => $startStatusValue) {
                     if ($startStatusKey === ArrayWorkflowItemFactory::KEY_METADATA) {
                         /**
                          * validate metadata
                          *
                          * 'A' => [
                          * 		'metadata' => [ 'key' => 'value']
                          * ]
                          */
                         if (is_array($startStatusDef[ArrayWorkflowItemFactory::KEY_METADATA])) {
                             if (!ArrayHelper::isAssociative($startStatusDef[ArrayWorkflowItemFactory::KEY_METADATA])) {
                                 throw new WorkflowException("Invalid metadata definition for status {$startStatusId} : associative array expected");
                             }
                         } else {
                             throw new WorkflowException("Invalid metadata definition for status {$startStatusId} : array expected");
                         }
                         $result[ArrayWorkflowItemFactory::KEY_NODES][$startStatusId][ArrayWorkflowItemFactory::KEY_METADATA] = $startStatusDef[ArrayWorkflowItemFactory::KEY_METADATA];
                     } elseif ($startStatusKey === ArrayWorkflowItemFactory::KEY_EDGES) {
                         $transitionDefinition = $startStatusDef[ArrayWorkflowItemFactory::KEY_EDGES];
                         if (is_string($transitionDefinition)) {
                             /**
                              *  'A' => [
                              *   	'transition' => 'A, B, WID/C'
                              *   ]
                              */
                             $ids = array_map('trim', explode(',', $transitionDefinition));
                             foreach ($ids as $id) {
                                 $pieces = $factory->parseWorkflowStatus($id, $wId, $model);
                                 $canEndStId = implode(ArrayWorkflowItemFactory::SEPARATOR_STATUS_NAME, $pieces);
                                 $endStatusIdIndex[] = $canEndStId;
                                 $result[ArrayWorkflowItemFactory::KEY_NODES][$startStatusId][ArrayWorkflowItemFactory::KEY_EDGES][$canEndStId] = [];
                             }
                         } elseif (is_array($transitionDefinition)) {
                             /**
                              *  'transition' => [ ...]
                              */
                             foreach ($transitionDefinition as $tKey => $tValue) {
                                 if (is_string($tKey)) {
                                     /**
                                      * 'transition' => [ 'A' => [] ]
                                      */
                                     $endStatusId = $tKey;
                                     if (!is_array($tValue)) {
                                         throw new WorkflowException("Wrong definition for between {$startStatusId} and {$endStatusId} : array expected");
                                     }
                                     $transDef = $tValue;
                                 } elseif (is_string($tValue)) {
                                     /**
                                      * 'transition' =>  'A' 
                                      */
                                     $endStatusId = $tValue;
                                     $transDef = null;
                                 } else {
                                     throw new WorkflowException("Wrong transition definition for status {$startStatusId} : key = " . VarDumper::dumpAsString($tKey) . " value = " . VarDumper::dumpAsString($tValue));
                                 }
                                 $pieces = $factory->parseWorkflowStatus($endStatusId, $wId, $model);
                                 $canEndStId = implode(ArrayWorkflowItemFactory::SEPARATOR_STATUS_NAME, $pieces);
                                 $endStatusIdIndex[] = $canEndStId;
                                 if ($transDef != null) {
                                     $result[ArrayWorkflowItemFactory::KEY_NODES][$startStatusId][ArrayWorkflowItemFactory::KEY_EDGES][$canEndStId] = $transDef;
                                 } else {
                                     $result[ArrayWorkflowItemFactory::KEY_NODES][$startStatusId][ArrayWorkflowItemFactory::KEY_EDGES][$canEndStId] = [];
                                 }
                             }
                         } else {
                             throw new WorkflowException("Invalid transition definition format for status {$startStatusId} : string or array expected");
                         }
                     } elseif (is_string($startStatusKey)) {
                         $result[ArrayWorkflowItemFactory::KEY_NODES][$startStatusId][$startStatusKey] = $startStatusValue;
                     }
                 }
             }
         } else {
             //$startStatusDef is not array
             /**
              * Node IDS must be canonical and array keys
              * 'status' => [
              * 		'A'
              * ]
              *  turned into
              *
              * 'status' => [
              * 		'WID/A' => null
              * ]
              */
             $result[ArrayWorkflowItemFactory::KEY_NODES][$startStatusId] = null;
         }
     }
     // copy remaining workflow properties
     foreach ($definition as $propName => $propValue) {
         if ($propName !== 'initialStatusId' && $propName !== ArrayWorkflowItemFactory::KEY_NODES) {
             $result[$propName] = $propValue;
         }
     }
     if ($this->validate === true) {
         if (!in_array($initialStatusId, $startStatusIdIndex)) {
             throw new WorkflowException("Initial status not defined : {$initialStatusId}");
         }
         // detect not defined statuses
         $missingStatusIdSuspects = array_diff($endStatusIdIndex, $startStatusIdIndex);
         if (count($missingStatusIdSuspects) != 0) {
             $missingStatusId = [];
             foreach ($missingStatusIdSuspects as $id) {
                 list($thisWid, ) = $factory->parseWorkflowStatus($id, $wId, $model);
                 if ($thisWid == $wId) {
                     $missingStatusId[] = $id;
                     // refering to the same workflow, this Id is not defined
                 }
             }
             if (count($missingStatusId) != 0) {
                 throw new WorkflowException("One or more end status are not defined : " . VarDumper::dumpAsString($missingStatusId));
             }
         }
     }
     return $result;
 }
예제 #24
0
 public function testIsAssociative()
 {
     $this->assertFalse(ArrayHelper::isAssociative('test'));
     $this->assertFalse(ArrayHelper::isAssociative([]));
     $this->assertFalse(ArrayHelper::isAssociative([1, 2, 3]));
     $this->assertTrue(ArrayHelper::isAssociative(['name' => 1, 'value' => 'test']));
     $this->assertFalse(ArrayHelper::isAssociative(['name' => 1, 'value' => 'test', 3]));
     $this->assertTrue(ArrayHelper::isAssociative(['name' => 1, 'value' => 'test', 3], false));
 }
예제 #25
0
 /**
  * Resolve dependencies for a function.
  *
  * This method can be used to implement similar functionality as provided by [[invoke()]] in other
  * components.
  *
  * @param callable $callback callable to be invoked.
  * @param array $params The array of parameters for the function, can be either numeric or associative.
  * @return array The resolved dependencies.
  * @throws InvalidConfigException if a dependency cannot be resolved or if a dependency cannot be fulfilled.
  * @since 2.0.7
  */
 public function resolveCallableDependencies(callable $callback, $params = [])
 {
     if (is_array($callback)) {
         $reflection = new \ReflectionMethod($callback[0], $callback[1]);
     } else {
         $reflection = new \ReflectionFunction($callback);
     }
     $args = [];
     $associative = ArrayHelper::isAssociative($params);
     foreach ($reflection->getParameters() as $param) {
         $name = $param->getName();
         if (($class = $param->getClass()) !== null) {
             $className = $class->getName();
             if ($associative && isset($params[$name]) && $params[$name] instanceof $className) {
                 $args[] = $params[$name];
                 unset($params[$name]);
             } elseif (!$associative && isset($params[0]) && $params[0] instanceof $className) {
                 $args[] = array_shift($params);
             } elseif (Yii::$app->has($name) && ($obj = Yii::$app->get($name)) instanceof $className) {
                 $args[] = $obj;
             } else {
                 $args[] = $this->get($className);
             }
         } elseif ($associative && isset($params[$name])) {
             $args[] = $params[$name];
             unset($params[$name]);
         } elseif (!$associative && count($params)) {
             $args[] = array_shift($params);
         } elseif ($param->isDefaultValueAvailable()) {
             $args[] = $param->getDefaultValue();
         } elseif (!$param->isOptional()) {
             $funcName = $reflection->getName();
             throw new InvalidConfigException("Missing required parameter \"{$name}\" when calling \"{$funcName}\".");
         }
     }
     foreach ($params as $value) {
         $args[] = $value;
     }
     return $args;
 }
예제 #26
0
 /**
  * @param array $aggregation
  */
 protected function addFacetAggregation($aggregation)
 {
     if ($aggregation) {
         $aggregations = ArrayHelper::isAssociative($aggregation) ? [$aggregation] : $aggregation;
         foreach ($aggregations as $aggregation) {
             if (isset($aggregation['type'])) {
                 $this->addAggregation($aggregation['name'], $aggregation['type'], $aggregation['options']);
             } else {
                 $this->aggregations = array_merge($this->aggregations, [$aggregation['name'] => $aggregation['options']]);
             }
         }
     }
 }
예제 #27
0
 /**
  * Parse a workflow defined as a PHP Array.
  *
  * The workflow definition passed as argument is turned into an array that can be
  * used by the WorkflowFileSource components.
  *
  * @param string $wId
  * @param array $definition
  * @param raoul2000\workflow\source\file\WorkflowFileSource $source
  * @return array The parse workflow array definition
  * @throws WorkflowValidationException
  */
 public function parse($wId, $definition, $source)
 {
     $normalized = [];
     if (!isset($definition['initialStatusId'])) {
         throw new WorkflowValidationException('Missing "initialStatusId"');
     }
     list($workflowId, $statusId) = $source->parseStatusId($definition['initialStatusId'], $wId);
     $initialStatusId = $workflowId . WorkflowFileSource::SEPARATOR_STATUS_NAME . $statusId;
     if ($workflowId != $wId) {
         throw new WorkflowValidationException('Initial status must belong to workflow : ' . $initialStatusId);
     }
     if (!isset($definition[WorkflowFileSource::KEY_NODES])) {
         throw new WorkflowValidationException("No status definition found");
     }
     $normalized['initialStatusId'] = $initialStatusId;
     if (!\is_array($definition[WorkflowFileSource::KEY_NODES])) {
         throw new WorkflowValidationException('Invalid Status definition : array expected');
     }
     $startStatusIdIndex = [];
     $endStatusIdIndex = [];
     foreach ($definition[WorkflowFileSource::KEY_NODES] as $key => $value) {
         $startStatusId = null;
         $startStatusDef = null;
         if (is_string($key)) {
             /**
              * 'status' => ['A' => ???]
              */
             $startStatusId = $key;
             if ($value == null) {
                 $startStatusDef = $startStatusId;
                 // 'status' => ['A' => null]
             } elseif (\is_array($value)) {
                 $startStatusDef = $value;
                 // 'status' => ['A' => [ ...] ]
             } else {
                 throw new WorkflowValidationException("Wrong definition for status {$startStatusId} : array expected");
             }
         } elseif (is_string($value)) {
             /**
              * 'status' => 'A'
              */
             $startStatusId = $value;
             $startStatusDef = $startStatusId;
         } else {
             throw new WorkflowValidationException("Wrong status definition : key = " . VarDumper::dumpAsString($key) . " value = " . VarDumper::dumpAsString($value));
         }
         list($workflowId, $statusId) = $source->parseStatusId($startStatusId, $wId);
         $startStatusId = $startStatusIdIndex[] = $workflowId . WorkflowFileSource::SEPARATOR_STATUS_NAME . $statusId;
         if ($workflowId != $wId) {
             throw new WorkflowValidationException('Status must belong to workflow : ' . $startStatusId);
         }
         if (is_array($startStatusDef)) {
             if (count($startStatusDef) == 0) {
                 /**
                  * empty status config array
                  *
                  * 'A' => []
                  */
                 $normalized[WorkflowFileSource::KEY_NODES][$startStatusId] = null;
             } else {
                 foreach ($startStatusDef as $startStatusKey => $startStatusValue) {
                     if ($startStatusKey == WorkflowFileSource::KEY_METADATA) {
                         /**
                          * validate metadata
                          *
                          * 'A' => [
                          * 		'metadata' => [ 'key' => 'value']
                          * ]
                          */
                         if (\is_array($startStatusDef[WorkflowFileSource::KEY_METADATA])) {
                             if (!ArrayHelper::isAssociative($startStatusDef[WorkflowFileSource::KEY_METADATA])) {
                                 throw new WorkflowValidationException("Invalid metadata definition for status {$startStatusId} : associative array expected");
                             }
                         } else {
                             throw new WorkflowValidationException("Invalid metadata definition for status {$startStatusId} : array expected");
                         }
                         $normalized[WorkflowFileSource::KEY_NODES][$startStatusId][WorkflowFileSource::KEY_METADATA] = $startStatusDef[WorkflowFileSource::KEY_METADATA];
                     } elseif ($startStatusKey == 'transition') {
                         $transitionDefinition = $startStatusDef['transition'];
                         if (\is_string($transitionDefinition)) {
                             /**
                              *  'A' => [
                              *   	'transition' => 'A, B, WID/C'
                              *   ]
                              */
                             $ids = array_map('trim', explode(',', $transitionDefinition));
                             foreach ($ids as $id) {
                                 $pieces = $source->parseStatusId($id, $wId);
                                 $canEndStId = \implode(WorkflowFileSource::SEPARATOR_STATUS_NAME, $pieces);
                                 $endStatusIdIndex[] = $canEndStId;
                                 $normalized[WorkflowFileSource::KEY_NODES][$startStatusId]['transition'][$canEndStId] = [];
                             }
                         } elseif (\is_array($transitionDefinition)) {
                             /**
                              *  'transition' => [ ...]
                              */
                             foreach ($transitionDefinition as $tkey => $tvalue) {
                                 if (\is_string($tkey)) {
                                     /**
                                      * 'transition' => [ 'A' => [] ]
                                      */
                                     $endStatusId = $tkey;
                                     if (!\is_array($tvalue)) {
                                         throw new WorkflowValidationException("Wrong definition for between {$startStatusId} and {$endStatusId} : array expected");
                                     }
                                     $transDef = $tvalue;
                                 } elseif (\is_string($tvalue)) {
                                     /**
                                      * 'transition' =>  'A'
                                      */
                                     $endStatusId = $tvalue;
                                     $transDef = null;
                                 } else {
                                     throw new WorkflowValidationException("Wrong transition definition for status {$startStatusId} : key = " . VarDumper::dumpAsString($tkey) . " value = " . VarDumper::dumpAsString($tvalue));
                                 }
                                 $pieces = $source->parseStatusId($endStatusId, $wId);
                                 $canEndStId = \implode(WorkflowFileSource::SEPARATOR_STATUS_NAME, $pieces);
                                 $endStatusIdIndex[] = $canEndStId;
                                 if ($transDef != null) {
                                     $normalized[WorkflowFileSource::KEY_NODES][$startStatusId]['transition'][$canEndStId] = $transDef;
                                 } else {
                                     $normalized[WorkflowFileSource::KEY_NODES][$startStatusId]['transition'][$canEndStId] = [];
                                 }
                             }
                         } else {
                             throw new WorkflowValidationException("Invalid transition definition format for status {$startStatusId} : string or array expected");
                         }
                     } elseif (\is_string($startStatusKey)) {
                         $normalized[WorkflowFileSource::KEY_NODES][$startStatusId][$startStatusKey] = $startStatusValue;
                     }
                 }
             }
         } else {
             //$startStatusDef is not array
             /**
              * Node IDS must be canonical and array keys
              * 'status' => [
              * 		'A'
              * ]
              *  turned into
              *
              * 'status' => [
              * 		'WID/A' => null
              * ]
              */
             $normalized[WorkflowFileSource::KEY_NODES][$startStatusId] = null;
         }
     }
     // copy remaining workflow properties
     foreach ($definition as $propName => $propValue) {
         if (is_string($propName)) {
             if ($propName != 'initialStatusId' && $propName != WorkflowFileSource::KEY_NODES) {
                 $normalized[$propName] = $propValue;
             }
         }
     }
     $this->validate($wId, $source, $initialStatusId, $startStatusIdIndex, $endStatusIdIndex);
     return $normalized;
 }
예제 #28
0
 protected function setMany($name, $value)
 {
     $this->relatedModels[$name] = [];
     unset($this->extraColumns[$name]);
     if ($value === null) {
         $this->relatedData[$name] = $value;
     } else {
         $this->relatedData[$name] = [];
         foreach ($value as $key => $item) {
             if (is_array($item) && !ArrayHelper::isAssociative($item)) {
                 $this->relatedData[$name][$key] = ArrayHelper::remove($item, 0);
                 $this->extraColumns[$name][$key] = $item;
             } else {
                 $this->relatedData[$name][$key] = $item;
             }
         }
         if ($this->isLoaded($name)) {
             $this->relatedModels[$name] = $this->relatedData[$name];
             $this->owner->populateRelation($name, $this->relatedData[$name]);
         }
     }
 }
예제 #29
0
 /**
  * Finds ActiveRecord instance(s) by the given condition.
  * This method is internally called by [[findOne()]] and [[findAll()]].
  * @param mixed $condition please refer to [[findOne()]] for the explanation of this parameter
  * @param boolean $one whether this method is called by [[findOne()]] or [[findAll()]]
  * @return static|static[]
  * @throws InvalidConfigException if there is no primary key defined
  * @internal
  */
 protected static function findByCondition($condition, $one)
 {
     $query = static::find();
     if (!ArrayHelper::isAssociative($condition)) {
         // query by primary key
         $primaryKey = static::primaryKey();
         if (isset($primaryKey[0])) {
             $pk = $primaryKey[0];
             if (!empty($query->join) || !empty($query->joinWith)) {
                 $pk = static::tableName() . '.' . $pk;
             }
             $condition = [$pk => $condition];
         } else {
             throw new InvalidConfigException('"' . get_called_class() . '" must have a primary key.');
         }
     }
     return $one ? $query->andWhere($condition)->one() : $query->andWhere($condition)->all();
 }
 /**
  * @inheritdoc
  */
 public function deserialize($wId, $definition, $factory, $model)
 {
     if (empty($wId)) {
         throw new WorkflowException("Missing argument : workflow Id");
     }
     if (!is_array($definition)) {
         throw new WorkflowException("Workflow definition must be provided as an array");
     }
     if (!ArrayHelper::isAssociative($definition)) {
         throw new WorkflowException("Workflow definition must be provided as associative array");
     }
     $normalized = [];
     $startStatusIdIndex = [];
     $endStatusIdIndex = [];
     foreach ($definition as $id => $targetStatusList) {
         list($workflowId, $statusId, ) = $factory->parseWorkflowStatus($id, $wId, $model);
         $absoluteStatusId = $workflowId . ArrayWorkflowItemFactory::SEPARATOR_STATUS_NAME . $statusId;
         if ($workflowId != $wId) {
             throw new WorkflowException('Status must belong to workflow : ' . $absoluteStatusId);
         }
         if (count($normalized) == 0) {
             $initialStatusId = $absoluteStatusId;
             $normalized['initialStatusId'] = $initialStatusId;
             $normalized[ArrayWorkflowItemFactory::KEY_NODES] = [];
         }
         $startStatusIdIndex[] = $absoluteStatusId;
         if (is_string($targetStatusList)) {
             $ids = array_map('trim', explode(',', $targetStatusList));
             $endStatusIds = $this->normalizeStatusIds($ids, $wId, $factory, $model);
         } elseif (is_array($targetStatusList)) {
             if (ArrayHelper::isAssociative($targetStatusList, false)) {
                 throw new WorkflowException("Associative array not supported (status : {$absoluteStatusId})");
             }
             $endStatusIds = $this->normalizeStatusIds($targetStatusList, $wId, $factory, $model);
         } elseif ($targetStatusList === null) {
             $endStatusIds = [];
         } else {
             throw new WorkflowException('End status list must be an array for status  : ' . $absoluteStatusId);
         }
         if (count($endStatusIds)) {
             $normalized[ArrayWorkflowItemFactory::KEY_NODES][$absoluteStatusId] = [ArrayWorkflowItemFactory::KEY_EDGES => array_fill_keys($endStatusIds, [])];
             $endStatusIdIndex = array_merge($endStatusIdIndex, $endStatusIds);
         } else {
             $normalized[ArrayWorkflowItemFactory::KEY_NODES][$absoluteStatusId] = null;
         }
     }
     if ($this->validate === true) {
         if (isset($initialStatusId) && !in_array($initialStatusId, $startStatusIdIndex)) {
             throw new WorkflowException("Initial status not defined : {$initialStatusId}");
         }
         // detect not defined statuses
         $missingStatusIdSuspects = array_diff($endStatusIdIndex, $startStatusIdIndex);
         if (count($missingStatusIdSuspects) != 0) {
             $missingStatusId = [];
             foreach ($missingStatusIdSuspects as $id) {
                 list($thisWid, , ) = $factory->parseWorkflowStatus($id, $wId, $model);
                 if ($thisWid == $wId) {
                     $missingStatusId[] = $id;
                     // refering to the same workflow, this Id is not defined
                 }
             }
             if (count($missingStatusId) != 0) {
                 throw new WorkflowException("One or more end status are not defined : " . VarDumper::dumpAsString($missingStatusId));
             }
         }
     }
     return $normalized;
 }