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; } }
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.'); } } }
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; }
/** * @inheritdoc */ public static function findAll($condition) { $query = static::find(); if (ArrayHelper::isAssociative($condition)) { return $query->andWhere($condition)->all(); } else { return static::mget((array) $condition); } }
/** * @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); }
/** * @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); } }
/** * 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; }
/** * @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); } }
/** * 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; } }
/** * @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.'); } } }
/** * 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); } } }
protected function normalizeEAttributeValue($value) { if (is_array($value) && ArrayHelper::isAssociative($value, false)) { $value = isset($value['value']) ? $value['value'] : null; } return $value; }
/** * 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']); } }
/** * @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; }
/** * 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(); }
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]); } } } }
/** * @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; }
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)); }
/** * 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; }
/** * @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']]); } } } }
/** * 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; }
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]); } } }
/** * 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; }