From be50bafad1a8fbaf51938088404efb9e197ca99c Mon Sep 17 00:00:00 2001 From: bethrezen Date: Sat, 25 Mar 2017 00:12:16 +0300 Subject: [PATCH] Add PartialTreeData action for AdjacencyList tree type - renders not full tree but a part of it --- .../AdjacencyList/PartialTreeDataAction.php | 156 ++++++++++++++++++ src/widgets/tree-input-src/styles.css | 4 + 2 files changed, 160 insertions(+) create mode 100644 src/actions/AdjacencyList/PartialTreeDataAction.php diff --git a/src/actions/AdjacencyList/PartialTreeDataAction.php b/src/actions/AdjacencyList/PartialTreeDataAction.php new file mode 100644 index 0000000..e50dab0 --- /dev/null +++ b/src/actions/AdjacencyList/PartialTreeDataAction.php @@ -0,0 +1,156 @@ + [ + * 'class' => PartialTreeDataAction::class, + * 'className' => Category::class, + * 'modelLabelAttribute' => 'defaultTranslation.name', + * + * ], + * ... + * ]; + * } + * ``` + */ +class PartialTreeDataAction extends Action +{ + + public $className; + + public $modelIdAttribute = 'id'; + + public $modelLabelAttribute = 'name'; + + public $modelParentAttribute = 'parent_id'; + + public $varyByTypeAttribute; + + public $queryParentAttribute = 'id'; + + public $querySortOrder = 'sort_order'; + + public $querySelectedAttribute = 'selected_id'; + /** + * Additional conditions for retrieving tree(ie. don't display nodes marked as deleted) + * @var array|\Closure + */ + public $whereCondition = []; + + /** + * Cache key prefix. Should be unique if you have multiple actions with different $whereCondition + * @var string|\Closure + */ + public $cacheKey = 'PartialTree'; + + /** + * Cache lifetime for the full tree + * @var int + */ + public $cacheLifeTime = 86400; + + public function init() + { + if ($this->className === null) { + throw new InvalidConfigException('Model name should be set in controller actions'); + } + if (!class_exists($this->className)) { + throw new InvalidConfigException('Model class does not exists'); + } + } + + public function run() + { + Yii::$app->response->format = Response::FORMAT_JSON; + + /** @var \yii\db\ActiveRecord $class */ + $class = $this->className; + + if (null === $current_selected_id = Yii::$app->request->get($this->querySelectedAttribute)) { + $current_selected_id = Yii::$app->request->get($this->queryParentAttribute); + } + + $parent_id = Yii::$app->request->get($this->queryParentAttribute, '#'); + if (!is_numeric($parent_id)) { + $parent_id = 0; + } + + $cacheKey = $this->cacheKey instanceof \Closure ? call_user_func($this->cacheKey) : $this->cacheKey; + + $cacheKey = "AdjacencyFullTreeData:$cacheKey:{$class}:{$this->querySortOrder}:$parent_id"; + + if (false === $result = Yii::$app->cache->get($cacheKey)) { + $query = $class::find() + ->orderBy([$this->querySortOrder => SORT_ASC]); + + if ($this->whereCondition instanceof \Closure) { + $query->where(call_user_func($this->whereCondition)); + } elseif (count($this->whereCondition) > 0) { + $query->where($this->whereCondition); + } + $query->andWhere([$this->modelParentAttribute => $parent_id]); + + if (null === $rows = $query->asArray()->all()) { + return []; + } + + $result = []; + + foreach ($rows as $row) { + $parent = ArrayHelper::getValue($row, $this->modelParentAttribute, 0); + $item = [ + 'id' => ArrayHelper::getValue($row, $this->modelIdAttribute, 0), + 'parent' => $parent ?: '#', + 'text' => ArrayHelper::getValue($row, $this->modelLabelAttribute, 'item'), + 'a_attr' => [ + 'data-id' => $row[$this->modelIdAttribute], + 'data-parent_id' => $row[$this->modelParentAttribute] + ], + 'children' => true, + ]; + + if (null !== $this->varyByTypeAttribute) { + $item['type'] = $row[$this->varyByTypeAttribute]; + } + + $result[$row[$this->modelIdAttribute]] = $item; + } + + Yii::$app->cache->set( + $cacheKey, + $result, + 86400, + new TagDependency([ + 'tags' => [ + NamingHelper::getCommonTag($class), + ], + ]) + ); + } + + if (array_key_exists($current_selected_id, $result)) { + $result[$current_selected_id] = array_merge( + $result[$current_selected_id], + ['state' => ['opened' => true, 'selected' => true]] + ); + } + + return array_values($result); + } +} diff --git a/src/widgets/tree-input-src/styles.css b/src/widgets/tree-input-src/styles.css index dc7ffd4..d140d9b 100644 --- a/src/widgets/tree-input-src/styles.css +++ b/src/widgets/tree-input-src/styles.css @@ -24,3 +24,7 @@ .tree-input__tree-container_active { display: block; } +.tree-input__selected-values { + line-height: 1.44; + padding: 6px 12px; +} \ No newline at end of file