├── .gitignore
├── .scrutinizer.yml
├── .travis.yml
├── AutoTreeTrait.php
├── LICENSE
├── README.md
├── composer.json
├── composer.lock
├── phpunit.xml.dist
└── tests
├── .gitignore
├── AlMpTest.php
├── AlNiTest.php
├── AlNsTest.php
├── ArrayDataSet.php
├── AutoTreeTraitTestCase.php
├── BaseTestCase.php
├── README.md
├── bootstrap.php
├── data
├── config.php
├── data-ni.php
└── data.php
├── migrations
└── TestMigration.php
└── models
├── NodeAlMp.php
├── NodeAlNi.php
├── NodeAlNs.php
└── NodeQuery.php
/.gitignore:
--------------------------------------------------------------------------------
1 | # phpstorm project files
2 | .idea
3 |
4 | # windows thumbnail cache
5 | Thumbs.db
6 |
7 | # composer vendor dir
8 | /vendor
9 |
10 | # composer itself is not needed
11 | composer.phar
12 |
13 | # Mac DS_Store Files
14 | .DS_Store
15 |
--------------------------------------------------------------------------------
/.scrutinizer.yml:
--------------------------------------------------------------------------------
1 | tools:
2 | external_code_coverage:
3 | timeout: 2100
4 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 |
3 | php:
4 | - 5.4
5 | - 5.5
6 | - 5.6
7 | - 7.0
8 | - 7.1
9 | - 7.2
10 | - hhvm
11 |
12 | sudo: false
13 |
14 | install:
15 | - composer self-update
16 | - composer update --prefer-dist --no-interaction
17 |
18 | before_script:
19 | - mysql --version
20 | - psql --version
21 | - mysql -e 'create database test;'
22 | - psql -U postgres -c 'CREATE DATABASE test;';
23 | - |
24 | if [ $TRAVIS_PHP_VERSION = '7.1' ]; then
25 | PHPUNIT_FLAGS="--coverage-clover=coverage.clover"
26 | fi
27 |
28 | script:
29 | - vendor/bin/phpunit $PHPUNIT_FLAGS
30 |
31 | after_script:
32 | - |
33 | if [ $TRAVIS_PHP_VERSION = '7.1' ]; then
34 | wget https://scrutinizer-ci.com/ocular.phar
35 | php ocular.phar code-coverage:upload --format=php-clover coverage.clover
36 | fi
37 |
--------------------------------------------------------------------------------
/AutoTreeTrait.php:
--------------------------------------------------------------------------------
1 | 'al',
24 | 'paulzi\adjacencylist\AdjacencyListBehavior' => 'al',
25 | 'paulzi\nestedSets\NestedSetsBehavior' => 'ns',
26 | 'paulzi\nestedsets\NestedSetsBehavior' => 'ns',
27 | 'paulzi\nestedIntervals\NestedIntervalsBehavior' => 'ni',
28 | 'paulzi\nestedintervals\NestedIntervalsBehavior' => 'ni',
29 | 'paulzi\materializedPath\MaterializedPathBehavior' => 'mp',
30 | 'paulzi\materializedpath\MaterializedPathBehavior' => 'mp',
31 | ];
32 | }
33 |
34 | /**
35 | *
36 | */
37 | private function autoTreeInit()
38 | {
39 | /** @var \yii\base\Component|self $this */
40 | $aliases = $this->autoTreeAliases();
41 | foreach ($this->getBehaviors() as $behavior) {
42 | $className = $behavior::className();
43 | if (isset($aliases[$className]) && !isset($this->_autoTreeMap[$aliases[$className]])) {
44 | $this->_autoTreeMap[$aliases[$className]] = $behavior;
45 | }
46 | }
47 | }
48 |
49 | /**
50 | * @param string $method
51 | * @param array $list
52 | * @param array $arguments
53 | * @param bool $firstOnly
54 | * @return mixed
55 | */
56 | private function autoTreeCall($method, $list, $arguments = [], $firstOnly = true)
57 | {
58 | if ($this->_autoTreeMap === null) {
59 | $this->autoTreeInit();
60 | }
61 |
62 | $result = null;
63 | $founded = false;
64 | foreach ($list as $alias) {
65 | if (isset($this->_autoTreeMap[$alias])) {
66 | $behavior = $this->_autoTreeMap[$alias];
67 | if (method_exists($behavior, $method)) {
68 | if ($this->_autoTreeReturnBehavior) {
69 | return $behavior;
70 | }
71 | $founded = true;
72 | $result = call_user_func_array([$behavior, $method], $arguments);
73 | if ($firstOnly) {
74 | return $result;
75 | }
76 | }
77 | }
78 | }
79 |
80 | if (!$founded) {
81 | throw new InvalidCallException("Method '{$method}' not founded");
82 | }
83 |
84 | return $result;
85 | }
86 |
87 | /**
88 | * @inheritdoc
89 | */
90 | public function __get($name)
91 | {
92 | /** @var \yii\db\BaseActiveRecord|self $this */
93 | // replace getParents() by getParentsOrdered() if behavior not support ordered query
94 | if ($name === 'parents') {
95 | $this->_autoTreeReturnBehavior = true;
96 | $behavior = $this->getParents();
97 | $this->_autoTreeReturnBehavior = false;
98 | if (method_exists($behavior, 'getParentsOrdered')) {
99 | $this->populateRelation($name, $behavior->getParentsOrdered());
100 | }
101 | }
102 | if ($name === 'descendants') {
103 | $this->_autoTreeReturnBehavior = true;
104 | $behavior = $this->getDescendants();
105 | $this->_autoTreeReturnBehavior = false;
106 | if (method_exists($behavior, 'getDescendantsOrdered')) {
107 | $this->populateRelation($name, $behavior->getDescendantsOrdered());
108 | }
109 | }
110 | return parent::__get($name);
111 | }
112 |
113 | /**
114 | * @param int|null $depth
115 | * @return \yii\db\ActiveQuery
116 | */
117 | public function getParents($depth = null)
118 | {
119 | return $this->autoTreeCall('getParents', ['mp', 'ns', 'ni', 'al'], [$depth]);
120 | }
121 |
122 | /**
123 | * @return \yii\db\ActiveQuery
124 | */
125 | public function getParent()
126 | {
127 | return $this->autoTreeCall('getParent', ['al', 'mp', 'ns', 'ni']);
128 | }
129 |
130 | /**
131 | * @return \yii\db\ActiveQuery
132 | */
133 | public function getRoot()
134 | {
135 | return $this->autoTreeCall('getRoot', ['mp', 'ns', 'ni', 'al']);
136 | }
137 |
138 | /**
139 | * @param int|null $depth
140 | * @param bool $andSelf
141 | * @return \yii\db\ActiveQuery
142 | */
143 | public function getDescendants($depth = null, $andSelf = false)
144 | {
145 | return $this->autoTreeCall('getDescendants', ['ns', 'ni', 'mp', 'al'], [$depth, $andSelf]);
146 | }
147 |
148 | /**
149 | * @return \yii\db\ActiveQuery
150 | */
151 | public function getChildren()
152 | {
153 | return $this->autoTreeCall('getChildren', ['al', 'ns', 'ni', 'mp']);
154 | }
155 |
156 | /**
157 | * @param int|null $depth
158 | * @return \yii\db\ActiveQuery
159 | */
160 | public function getLeaves($depth = null)
161 | {
162 | return $this->autoTreeCall('getLeaves', ['ns', 'al', 'mp', 'ni'], [$depth]);
163 | }
164 |
165 | /**
166 | * @return \yii\db\ActiveQuery
167 | * @throws \yii\base\NotSupportedException
168 | */
169 | public function getPrev()
170 | {
171 | return $this->autoTreeCall('getPrev', ['ns', 'mp', 'ni', 'al']);
172 | }
173 |
174 | /**
175 | * @return \yii\db\ActiveQuery
176 | * @throws \yii\base\NotSupportedException
177 | */
178 | public function getNext()
179 | {
180 | return $this->autoTreeCall('getNext', ['ns', 'mp', 'ni', 'al']);
181 | }
182 |
183 | /**
184 | * Populate children relations for self and all descendants
185 | * @param int $depth = null
186 | * @param string|array $with = null
187 | * @return self
188 | */
189 | public function populateTree($depth = null, $with = null)
190 | {
191 | return $this->autoTreeCall('populateTree', ['ns', 'ni', 'mp', 'al'], [$depth, $with]);
192 | }
193 |
194 | /**
195 | * @return bool
196 | */
197 | public function isRoot()
198 | {
199 | return $this->autoTreeCall('isRoot', ['al', 'ns', 'ni', 'mp']);
200 | }
201 |
202 | /**
203 | * @param \yii\db\BaseActiveRecord $node
204 | * @return bool
205 | */
206 | public function isChildOf($node)
207 | {
208 | return $this->autoTreeCall('isChildOf', ['ns', 'ni', 'mp', 'al'], [$node]);
209 | }
210 |
211 | /**
212 | * @return bool
213 | */
214 | public function isLeaf()
215 | {
216 | return $this->autoTreeCall('isLeaf', ['ns', 'al', 'ni', 'mp']);
217 | }
218 |
219 | /**
220 | * @return $this
221 | */
222 | public function makeRoot()
223 | {
224 | return $this->autoTreeCall('makeRoot', ['al', 'ns', 'ni', 'mp'], [], false);
225 | }
226 |
227 | /**
228 | * @param \yii\db\BaseActiveRecord $node
229 | * @return $this
230 | */
231 | public function prependTo($node)
232 | {
233 | return $this->autoTreeCall('prependTo', ['al', 'ns', 'ni', 'mp'], [$node], false);
234 | }
235 |
236 | /**
237 | * @param \yii\db\BaseActiveRecord $node
238 | * @return $this
239 | */
240 | public function appendTo($node)
241 | {
242 | return $this->autoTreeCall('appendTo', ['al', 'ns', 'ni', 'mp'], [$node], false);
243 | }
244 |
245 | /**
246 | * @param \yii\db\BaseActiveRecord $node
247 | * @return $this
248 | */
249 | public function insertBefore($node)
250 | {
251 | return $this->autoTreeCall('insertBefore', ['al', 'ns', 'ni', 'mp'], [$node], false);
252 | }
253 |
254 | /**
255 | * @param \yii\db\BaseActiveRecord $node
256 | * @return $this
257 | */
258 | public function insertAfter($node)
259 | {
260 | return $this->autoTreeCall('insertAfter', ['al', 'ns', 'ni', 'mp'], [$node], false);
261 | }
262 |
263 | /**
264 | * @return bool|int
265 | * @throws \Exception
266 | * @throws \yii\db\Exception
267 | */
268 | public function deleteWithChildren()
269 | {
270 | /** @var \yii\db\BaseActiveRecord|self $this */
271 | $this->autoTreeCall('preDeleteWithChildren', ['ns', 'ni', 'mp', 'al'], [], false);
272 | return $this->autoTreeCall('deleteWithChildren', ['ns', 'ni', 'mp', 'al']);
273 | }
274 | }
275 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 PaulZi (pavel.zimakoff@gmail.com)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Yii2 Auto Tree Trait
2 |
3 | Allow apply multiple tree behavior for ActiveRecord in Yii2.
4 |
5 | For selecting methods used by the most rapid behavior. For modifying methods - call all attached behaviors.
6 |
7 | If you are using the adjacency list for a get list of the parents or the descendants as relation will be used getParentsOrdered() or getDescendantsOrdered().
8 |
9 | [](https://packagist.org/packages/paulzi/yii2-auto-tree)
10 | [](https://scrutinizer-ci.com/g/paulzi/yii2-auto-tree/?branch=master)
11 | [](https://travis-ci.org/paulzi/yii2-auto-tree)
12 | [](https://packagist.org/packages/paulzi/yii2-auto-tree)
13 |
14 | ## Install
15 |
16 | Install via Composer:
17 |
18 | ```bash
19 | composer require paulzi/yii2-auto-tree
20 | ```
21 |
22 | or add
23 |
24 | ```bash
25 | "paulzi/yii2-auto-tree" : "^1.1"
26 | ```
27 |
28 | to the `require` section of your `composer.json` file.
29 |
30 | ## Configuring
31 |
32 | Install and configure one or more behaviors:
33 |
34 | - [Adjacency List](https://github.com/paulzi/yii2-adjacency-list)
35 | - [Nested Sets](https://github.com/paulzi/yii2-nested-sets)
36 | - [Nested Intervals](https://github.com/paulzi/yii2-nested-intervals)
37 | - [Materialized Path](https://github.com/paulzi/yii2-materialized-path)
38 |
39 | And use AutoTreeTrait in model.
40 |
41 | ```php
42 | use paulzi\adjacencylist\AdjacencyListBehavior;
43 | use paulzi\nestedsets\NestedSetsBehavior;
44 | use paulzi\autotree\AutoTreeTrait;
45 |
46 | class Sample extends \yii\db\ActiveRecord
47 | {
48 | use AutoTreeTrait;
49 |
50 | public function behaviors() {
51 | return [
52 | ['class' => AdjacencyListBehavior::className()],
53 | ['class' => NestedSetsBehavior::className()],
54 | ];
55 | }
56 | }
57 | ```
58 |
59 | ## Extending
60 |
61 | If you want to change the order call behavior, override the appropriate methods:
62 |
63 | ```php
64 | use paulzi\autotree\AutoTreeTrait;
65 |
66 | class Sample extends \yii\db\ActiveRecord
67 | {
68 | use AutoTreeTrait;
69 |
70 | /**
71 | * @param int|null $depth
72 | * @return \yii\db\ActiveQuery
73 | */
74 | public function getParents($depth = null)
75 | {
76 | return $this->autoTreeCall('getParents', ['al', 'mp', 'ns', 'ni'], [$depth]);
77 | }
78 | }
79 | ```
80 |
81 | If you want to change the list of classes of behaviors:
82 |
83 | ```php
84 | use paulzi\autotree\AutoTreeTrait;
85 |
86 | class Sample extends \yii\db\ActiveRecord
87 | {
88 | use AutoTreeTrait;
89 |
90 | /**
91 | * @return array
92 | */
93 | private static function autoTreeAliases()
94 | {
95 | return [
96 | 'example\adjacencylist\AdjacencyListBehavior' => 'al',
97 | 'example\nestedsets\NestedSetsBehavior' => 'ns',
98 | 'example\nestedintervals\NestedIntervalsBehavior' => 'ni',
99 | 'example\materializedpath\MaterializedPathBehavior' => 'mp',
100 | ];
101 | }
102 | }
103 | ```
104 |
105 | ## Behaviors speed comparison
106 | ```
107 | Name DB Queries DB Time Time Mem
108 |
109 | Test 1. Insert. Filling (3 level by 12 child)
110 | Adjacency List 5811 1,567 ms 9,591 ms 71.3 MB
111 | Nested Sets 7697 6,672 ms 25,019 ms 105.9 MB
112 | Nested Intervals amount=24 5813 1,765 ms 10,442 ms 78.7 MB
113 | Nested Intervals amount=12 noPrepend noIns. 5813 1,750 ms 10,223 ms 78.7 MB
114 | Materialized Path (identity pr. key mode) 7696 3,169 ms 13,726 ms 92.5 MB
115 | Materialized Path (attribute mode) 5811 1,690 ms 9,504 ms 71.6 MB
116 |
117 | Test 2. Insert. Filling (6 level by 3 child)
118 | Adjacency List 3642 982 ms 5,812 ms 44.5 MB
119 | Nested Sets 4736 5,447 ms 17,859 ms 65.0 MB
120 | Nested Intervals amount=10 3644 1,275 ms 5,976 ms 48.9 MB
121 | Nested Intervals amount=3 noPrepend noIns. 3644 1,271 ms 5,993 ms 48.9 MB
122 | Materialized Path (identity pr. key mode) 4735 1,316 ms 6,920 ms 57.3 MB
123 | Materialized Path (attribute mode) 3642 1,129 ms 5,507 ms 44.6 MB
124 |
125 | Test 3. Insert in begin <4% (20 in 19657 nodes)
126 | Adjacency List 100 36 ms 190 ms 4.6 MB
127 | PaulZi 100 15,768 ms 16,712 ms 4.7 MB
128 | Nested Intervals 82 21 ms 150 ms 4.7 MB
129 | Materialized Path (identity pr. key mode) 120 98 ms 355 ms 4.8 MB
130 | Materialized Path (attribute mode) 100 74 ms 334 ms 4.6 MB
131 |
132 | Test 4. Insert in middle >46% <50% (20 in 19657 nodes)
133 | Adjacency List 100 24 ms 150 ms 4.6 MB
134 | Nested Sets 100 8,212 ms 8,799 ms 4.7 MB
135 | Nested Intervals 82 269 ms 593 ms 4.7 MB
136 | Materialized Path (identity pr. key mode) 120 35 ms 196 ms 4.9 MB
137 | Materialized Path (attribute mode) 100 287 ms 494 ms 4.6 MB
138 |
139 | Test 5. Insert in end >96% (20 in 19657 nodes)
140 | Adjacency List 100 31 ms 214 ms 4.5 MB
141 | Nested Sets 100 487 ms 899 ms 4.7 MB
142 | Nested Intervals 83 46 ms 187 ms 4.7 MB
143 | Materialized Path (identity pr. key mode) 120 34 ms 229 ms 4.8 MB
144 | Materialized Path (attribute mode) 100 470 ms 718 ms 4.6 MB
145 |
146 | Test 6. Delete from begin <4% (20 in 19657 nodes)
147 | Adjacency List parentJoin=0 childrenJoin=0 60 169 ms 257 ms 3.8 MB
148 | Adjacency List parentJoin=3 childrenJoin=3 60 87 ms 162 ms 3.8 MB
149 | Nested Sets 100 16,480 ms 16,902 ms 4.7 MB
150 | Nested Intervals 60 164 ms 250 ms 4.2 MB
151 | Materialized Path (identity pr. key mode) 60 87 ms 201 ms 4.0 MB
152 | Materialized Path (attribute mode) 60 122 ms 219 ms 4.0 MB
153 |
154 | Test 7. Insert. Random append (5 levels, 1000 nodes)
155 | Adjacency List 4001 1,062 ms 5,976 ms 46.1 MB
156 | Nested Sets 5003 5,428 ms 17,334 ms 64.8 MB
157 | Nested Intervals amount=10 8497 23,301 ms 41,060 ms 120.7 MB
158 | Nested Intervals x64 amount=10 7092 11,330 ms 23,618 ms 97.5 MB
159 | Nested Intervals amount=200,25 noPrep noIns 4009 1,431 ms 6,490 ms 50.2 MB
160 | Nested Intervals x64 a=250,30 noPrep noIns 4003 1,421 ms 6,615 ms 50.0 MB
161 | Materialized Path (identity pr. key mode) 5003 1,621 ms 8,184 ms 57.8 MB
162 | Materialized Path (attribute mode) 4002 1,269 ms 6,169 ms 46.2 MB
163 |
164 | Test 8. Insert. Random operation (5 levels, 1000 nodes)
165 | Adjacency List 4383 1,330 ms 6,147 ms 53.0 MB
166 | Nested Sets 5003 9,577 ms 24,334 ms 64.8 MB
167 | Nested Intervals amount=10 7733 8,123 ms 24,031 ms 107.2 MB
168 | Nested Intervals x64 default amount=10 5663 3,761 ms 14,084 ms 75.6 MB
169 | Nested Intervals amount=200,25 4175 1,548 ms 7,223 ms 52.8 MB
170 | Nested Intervals x64 a=250,30 reserve=2 4003 1,541 ms 6,753 ms 50.0 MB
171 | Materialized Path (identity pr. key mode) 5392 3,211 ms 11,771 ms 65.0 MB
172 | Materialized Path (attribute mode) 4377 2,902 ms 10,132 ms 53.2 MB
173 |
174 | Test 9. Move random in begin <4% (20 in 19657 nodes)
175 | Adjacency List 112 39 ms 261 ms 4.5 MB
176 | Nested Sets 140 218 ms 566 ms 5.5 MB
177 | Nested Intervals 160 180 ms 573 ms 6.0 MB
178 | Materialized Path (identity pr. key mode) 128 38 ms 307 ms 4.9 MB
179 | Materialized Path (attribute mode) 128 159 ms 495 ms 4.9 MB
180 |
181 | Test 10. Move random from end to begin <4% >96% (20 of 19657 nodes)
182 | Nested Sets 140 16,991 ms 17,845 ms 5.5 MB
183 | Nested Intervals 160 16,972 ms 17,854 ms 6.0 MB
184 | Materialized Path (identity pr. key mode) 132 49 ms 319 ms 4.9 MB
185 | Materialized Path (attribute mode) 132 205 ms 502 ms 4.9 MB
186 | Adjacency List 112 33 ms 217 ms 4.5 MB
187 |
188 | Test 11. Select all nodes (19657 nodes)
189 | Adjacency List 1 33 ms 890 ms 179.1 MB
190 | Nested Sets 1 40 ms 1,208 ms 215.2 MB
191 | Nested Intervals 1 42 ms 1,247 ms 225.3 MB
192 | Materialized Path (identity pr. key mode) 1 46 ms 1,240 ms 209.0 MB
193 | Materialized Path (attribute mode) 1 44 ms 1,106 ms 209.0 MB
194 |
195 | Test 12. Select children and descendants (for 819 nodes in middle of 19657 nodes)
196 | Adjacency List parentJoin=0 childrenJoin=0 2562 720 ms 1,969 ms 36.9 MB
197 | Adjacency List parentJoin=3 childrenJoin=3 2461 704 ms 1,966 ms 35.3 MB
198 | Nested Sets 1641 522 ms 1,585 ms 25.0 MB
199 | Nested Intervals 1641 579 ms 1,657 ms 25.0 MB
200 | Materialized Path (identity pr. key mode) 1641 569 ms 1,626 ms 23.4 MB
201 | Materialized Path (attribute mode) 1641 793 ms 6,552 ms 44.7 MB
202 |
203 | Test 13. Select parents (for 819 nodes in middle of 19657 nodes)
204 | Adjacency List parentJoin=0 childrenJoin=0 3180 948 ms 2,304 ms 51.2 MB
205 | Adjacency List parentJoin=3 childrenJoin=3 1641 486 ms 1,495 ms 30.8 MB
206 | Nested Sets 821 3,238 ms 3,979 ms 20.7 MB
207 | Nested Intervals 821 3,292 ms 4,147 ms 22.0 MB
208 | Materialized Path (identity pr. key mode) 821 292 ms 902 ms 21.2 MB
209 | Materialized Path (attribute mode) 821 582 ms 4,574 ms 24.7 MB
210 |
211 | Test 14. Select next/prev (for 819 nodes in middle of 19657 nodes)
212 | Adjacency List parentJoin=0 childrenJoin=0 1641 535 ms 1,442 ms 23.7 MB
213 | Adjacency List parentJoin=3 childrenJoin=3 1641 508 ms 1,421 ms 23.6 MB
214 | Nested Sets 1641 513 ms 1,428 ms 24.5 MB
215 | Nested Intervals 1641 19,681 ms 21,326 ms 27.5 MB
216 | Materialized Path (identity pr. key mode) 1641 730 ms 1,695 ms 24.3 MB
217 | Materialized Path (attribute mode) 1641 1,892 ms 2,964 ms 24.3 MB
218 |
219 | Test 15. Select leaves (for 819 nodes in middle of 19657 nodes)
220 | Adjacency List parentJoin=0 childrenJoin=0 1833 568 ms 1,743 ms 32.6 MB
221 | Adjacency List parentJoin=3 childrenJoin=3 1732 556 ms 1,891 ms 31.3 MB
222 | Nested Sets 821 305 ms 908 ms 18.4 MB
223 | Nested Intervals 821 10,450 ms 11,166 ms 18.8 MB
224 | Materialized Path (identity pr. key mode) 821 7,968 ms 8,434 ms 18.5 MB
225 | Materialized Path (attribute mode) 821 14,349 ms 19,105 ms 21.3 MB
226 | ```
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "paulzi/yii2-auto-tree",
3 | "description": "Allow apply multiple tree behavior for ActiveRecord in Yii2",
4 | "keywords": ["yii2", "auto tree", "adjacency list", "nested sets", "nested intervals", "materialized path"],
5 | "type": "yii2-extension",
6 | "license": "MIT",
7 | "support": {
8 | "issues": "https://github.com/paulzi/yii2-auto-tree/issues?state=open",
9 | "source": "https://github.com/paulzi/yii2-auto-tree"
10 | },
11 | "authors": [
12 | {
13 | "name": "PaulZi",
14 | "email": "pavel.zimakoff@gmail.com"
15 | }
16 | ],
17 | "repositories": [
18 | {
19 | "type": "composer",
20 | "url": "https://asset-packagist.org"
21 | }
22 | ],
23 | "minimum-stability": "stable",
24 | "require": {
25 | "php": ">=5.4.0",
26 | "yiisoft/yii2": "~2.0.0"
27 | },
28 | "require-dev": {
29 | "paulzi/yii2-adjacency-list": "^2.0.3",
30 | "paulzi/yii2-nested-sets": "^1.0.4",
31 | "paulzi/yii2-nested-intervals": "^1.0.5",
32 | "paulzi/yii2-materialized-path": "^2.0.6",
33 | "phpunit/phpunit": "~4.0",
34 | "phpunit/dbunit": "~1.0"
35 | },
36 | "autoload": {
37 | "psr-4": {
38 | "paulzi\\autotree\\": ""
39 | }
40 | }
41 | }
--------------------------------------------------------------------------------
/composer.lock:
--------------------------------------------------------------------------------
1 | {
2 | "_readme": [
3 | "This file locks the dependencies of your project to a known state",
4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
5 | "This file is @generated automatically"
6 | ],
7 | "hash": "cf2f1500a4429ed3ee346d88dd0361be",
8 | "content-hash": "e46c01d12b85d958824c471632571f5a",
9 | "packages": [
10 | {
11 | "name": "bower-asset/jquery",
12 | "version": "2.2.4",
13 | "source": {
14 | "type": "git",
15 | "url": "https://github.com/jquery/jquery-dist.git",
16 | "reference": "c0185ab7c75aab88762c5aae780b9d83b80eda72"
17 | },
18 | "dist": {
19 | "type": "zip",
20 | "url": "https://api.github.com/repos/jquery/jquery-dist/zipball/c0185ab7c75aab88762c5aae780b9d83b80eda72",
21 | "reference": "c0185ab7c75aab88762c5aae780b9d83b80eda72",
22 | "shasum": ""
23 | },
24 | "type": "bower-asset-library",
25 | "extra": {
26 | "bower-asset-main": "dist/jquery.js",
27 | "bower-asset-ignore": [
28 | "package.json"
29 | ]
30 | },
31 | "license": [
32 | "MIT"
33 | ],
34 | "keywords": [
35 | "browser",
36 | "javascript",
37 | "jquery",
38 | "library"
39 | ]
40 | },
41 | {
42 | "name": "bower-asset/jquery.inputmask",
43 | "version": "3.2.7",
44 | "source": {
45 | "type": "git",
46 | "url": "https://github.com/RobinHerbots/jquery.inputmask.git",
47 | "reference": "5a72c563b502b8e05958a524cdfffafe9987be38"
48 | },
49 | "dist": {
50 | "type": "zip",
51 | "url": "https://api.github.com/repos/RobinHerbots/jquery.inputmask/zipball/5a72c563b502b8e05958a524cdfffafe9987be38",
52 | "reference": "5a72c563b502b8e05958a524cdfffafe9987be38",
53 | "shasum": ""
54 | },
55 | "require": {
56 | "bower-asset/jquery": ">=1.7"
57 | },
58 | "type": "bower-asset-library",
59 | "extra": {
60 | "bower-asset-main": [
61 | "./dist/inputmask/inputmask.js"
62 | ],
63 | "bower-asset-ignore": [
64 | "**/*",
65 | "!dist/*",
66 | "!dist/inputmask/*",
67 | "!dist/min/*",
68 | "!dist/min/inputmask/*",
69 | "!extra/bindings/*",
70 | "!extra/dependencyLibs/*",
71 | "!extra/phone-codes/*"
72 | ]
73 | },
74 | "license": [
75 | "http://opensource.org/licenses/mit-license.php"
76 | ],
77 | "description": "jquery.inputmask is a jquery plugin which create an input mask.",
78 | "keywords": [
79 | "form",
80 | "input",
81 | "inputmask",
82 | "jquery",
83 | "mask",
84 | "plugins"
85 | ]
86 | },
87 | {
88 | "name": "bower-asset/punycode",
89 | "version": "v1.3.2",
90 | "source": {
91 | "type": "git",
92 | "url": "https://github.com/bestiejs/punycode.js.git",
93 | "reference": "38c8d3131a82567bfef18da09f7f4db68c84f8a3"
94 | },
95 | "dist": {
96 | "type": "zip",
97 | "url": "https://api.github.com/repos/bestiejs/punycode.js/zipball/38c8d3131a82567bfef18da09f7f4db68c84f8a3",
98 | "reference": "38c8d3131a82567bfef18da09f7f4db68c84f8a3",
99 | "shasum": ""
100 | },
101 | "type": "bower-asset-library",
102 | "extra": {
103 | "bower-asset-main": "punycode.js",
104 | "bower-asset-ignore": [
105 | "coverage",
106 | "tests",
107 | ".*",
108 | "component.json",
109 | "Gruntfile.js",
110 | "node_modules",
111 | "package.json"
112 | ]
113 | }
114 | },
115 | {
116 | "name": "bower-asset/yii2-pjax",
117 | "version": "v2.0.6",
118 | "source": {
119 | "type": "git",
120 | "url": "https://github.com/yiisoft/jquery-pjax.git",
121 | "reference": "60728da6ade5879e807a49ce59ef9a72039b8978"
122 | },
123 | "dist": {
124 | "type": "zip",
125 | "url": "https://api.github.com/repos/yiisoft/jquery-pjax/zipball/60728da6ade5879e807a49ce59ef9a72039b8978",
126 | "reference": "60728da6ade5879e807a49ce59ef9a72039b8978",
127 | "shasum": ""
128 | },
129 | "require": {
130 | "bower-asset/jquery": ">=1.8"
131 | },
132 | "type": "bower-asset-library",
133 | "extra": {
134 | "bower-asset-main": "./jquery.pjax.js",
135 | "bower-asset-ignore": [
136 | ".travis.yml",
137 | "Gemfile",
138 | "Gemfile.lock",
139 | "CONTRIBUTING.md",
140 | "vendor/",
141 | "script/",
142 | "test/"
143 | ]
144 | },
145 | "license": [
146 | "MIT"
147 | ]
148 | },
149 | {
150 | "name": "cebe/markdown",
151 | "version": "1.1.0",
152 | "source": {
153 | "type": "git",
154 | "url": "https://github.com/cebe/markdown.git",
155 | "reference": "54a2c49de31cc44e864ebf0500a35ef21d0010b2"
156 | },
157 | "dist": {
158 | "type": "zip",
159 | "url": "https://api.github.com/repos/cebe/markdown/zipball/54a2c49de31cc44e864ebf0500a35ef21d0010b2",
160 | "reference": "54a2c49de31cc44e864ebf0500a35ef21d0010b2",
161 | "shasum": ""
162 | },
163 | "require": {
164 | "lib-pcre": "*",
165 | "php": ">=5.4.0"
166 | },
167 | "require-dev": {
168 | "cebe/indent": "*",
169 | "facebook/xhprof": "*@dev",
170 | "phpunit/phpunit": "4.1.*"
171 | },
172 | "bin": [
173 | "bin/markdown"
174 | ],
175 | "type": "library",
176 | "extra": {
177 | "branch-alias": {
178 | "dev-master": "1.1.x-dev"
179 | }
180 | },
181 | "autoload": {
182 | "psr-4": {
183 | "cebe\\markdown\\": ""
184 | }
185 | },
186 | "notification-url": "https://packagist.org/downloads/",
187 | "license": [
188 | "MIT"
189 | ],
190 | "authors": [
191 | {
192 | "name": "Carsten Brandt",
193 | "email": "mail@cebe.cc",
194 | "homepage": "http://cebe.cc/",
195 | "role": "Creator"
196 | }
197 | ],
198 | "description": "A super fast, highly extensible markdown parser for PHP",
199 | "homepage": "https://github.com/cebe/markdown#readme",
200 | "keywords": [
201 | "extensible",
202 | "fast",
203 | "gfm",
204 | "markdown",
205 | "markdown-extra"
206 | ],
207 | "time": "2015-03-06 05:28:07"
208 | },
209 | {
210 | "name": "ezyang/htmlpurifier",
211 | "version": "v4.8.0",
212 | "source": {
213 | "type": "git",
214 | "url": "https://github.com/ezyang/htmlpurifier.git",
215 | "reference": "d0c392f77d2f2a3dcf7fcb79e2a1e2b8804e75b2"
216 | },
217 | "dist": {
218 | "type": "zip",
219 | "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/d0c392f77d2f2a3dcf7fcb79e2a1e2b8804e75b2",
220 | "reference": "d0c392f77d2f2a3dcf7fcb79e2a1e2b8804e75b2",
221 | "shasum": ""
222 | },
223 | "require": {
224 | "php": ">=5.2"
225 | },
226 | "type": "library",
227 | "autoload": {
228 | "psr-0": {
229 | "HTMLPurifier": "library/"
230 | },
231 | "files": [
232 | "library/HTMLPurifier.composer.php"
233 | ]
234 | },
235 | "notification-url": "https://packagist.org/downloads/",
236 | "license": [
237 | "LGPL"
238 | ],
239 | "authors": [
240 | {
241 | "name": "Edward Z. Yang",
242 | "email": "admin@htmlpurifier.org",
243 | "homepage": "http://ezyang.com"
244 | }
245 | ],
246 | "description": "Standards compliant HTML filter written in PHP",
247 | "homepage": "http://htmlpurifier.org/",
248 | "keywords": [
249 | "html"
250 | ],
251 | "time": "2016-07-16 12:58:58"
252 | },
253 | {
254 | "name": "yiisoft/yii2",
255 | "version": "2.0.9",
256 | "source": {
257 | "type": "git",
258 | "url": "https://github.com/yiisoft/yii2-framework.git",
259 | "reference": "2b75151ea60e1fd820046416eee2e89c3dda1133"
260 | },
261 | "dist": {
262 | "type": "zip",
263 | "url": "https://api.github.com/repos/yiisoft/yii2-framework/zipball/2b75151ea60e1fd820046416eee2e89c3dda1133",
264 | "reference": "2b75151ea60e1fd820046416eee2e89c3dda1133",
265 | "shasum": ""
266 | },
267 | "require": {
268 | "bower-asset/jquery": "2.2.*@stable | 2.1.*@stable | 1.11.*@stable | 1.12.*@stable",
269 | "bower-asset/jquery.inputmask": "~3.2.2",
270 | "bower-asset/punycode": "1.3.*",
271 | "bower-asset/yii2-pjax": "~2.0.1",
272 | "cebe/markdown": "~1.0.0 | ~1.1.0",
273 | "ext-ctype": "*",
274 | "ext-mbstring": "*",
275 | "ezyang/htmlpurifier": "~4.6",
276 | "lib-pcre": "*",
277 | "php": ">=5.4.0",
278 | "yiisoft/yii2-composer": "~2.0.4"
279 | },
280 | "bin": [
281 | "yii"
282 | ],
283 | "type": "library",
284 | "extra": {
285 | "branch-alias": {
286 | "dev-master": "2.0.x-dev"
287 | }
288 | },
289 | "autoload": {
290 | "psr-4": {
291 | "yii\\": ""
292 | }
293 | },
294 | "notification-url": "https://packagist.org/downloads/",
295 | "license": [
296 | "BSD-3-Clause"
297 | ],
298 | "authors": [
299 | {
300 | "name": "Qiang Xue",
301 | "email": "qiang.xue@gmail.com",
302 | "homepage": "http://www.yiiframework.com/",
303 | "role": "Founder and project lead"
304 | },
305 | {
306 | "name": "Alexander Makarov",
307 | "email": "sam@rmcreative.ru",
308 | "homepage": "http://rmcreative.ru/",
309 | "role": "Core framework development"
310 | },
311 | {
312 | "name": "Maurizio Domba",
313 | "homepage": "http://mdomba.info/",
314 | "role": "Core framework development"
315 | },
316 | {
317 | "name": "Carsten Brandt",
318 | "email": "mail@cebe.cc",
319 | "homepage": "http://cebe.cc/",
320 | "role": "Core framework development"
321 | },
322 | {
323 | "name": "Timur Ruziev",
324 | "email": "resurtm@gmail.com",
325 | "homepage": "http://resurtm.com/",
326 | "role": "Core framework development"
327 | },
328 | {
329 | "name": "Paul Klimov",
330 | "email": "klimov.paul@gmail.com",
331 | "role": "Core framework development"
332 | },
333 | {
334 | "name": "Dmitry Naumenko",
335 | "email": "d.naumenko.a@gmail.com",
336 | "role": "Core framework development"
337 | }
338 | ],
339 | "description": "Yii PHP Framework Version 2",
340 | "homepage": "http://www.yiiframework.com/",
341 | "keywords": [
342 | "framework",
343 | "yii2"
344 | ],
345 | "time": "2016-07-11 13:36:42"
346 | },
347 | {
348 | "name": "yiisoft/yii2-composer",
349 | "version": "2.0.4",
350 | "source": {
351 | "type": "git",
352 | "url": "https://github.com/yiisoft/yii2-composer.git",
353 | "reference": "7452fd908a5023b8bb5ea1b123a174ca080de464"
354 | },
355 | "dist": {
356 | "type": "zip",
357 | "url": "https://api.github.com/repos/yiisoft/yii2-composer/zipball/7452fd908a5023b8bb5ea1b123a174ca080de464",
358 | "reference": "7452fd908a5023b8bb5ea1b123a174ca080de464",
359 | "shasum": ""
360 | },
361 | "require": {
362 | "composer-plugin-api": "^1.0"
363 | },
364 | "type": "composer-plugin",
365 | "extra": {
366 | "class": "yii\\composer\\Plugin",
367 | "branch-alias": {
368 | "dev-master": "2.0.x-dev"
369 | }
370 | },
371 | "autoload": {
372 | "psr-4": {
373 | "yii\\composer\\": ""
374 | }
375 | },
376 | "notification-url": "https://packagist.org/downloads/",
377 | "license": [
378 | "BSD-3-Clause"
379 | ],
380 | "authors": [
381 | {
382 | "name": "Qiang Xue",
383 | "email": "qiang.xue@gmail.com"
384 | }
385 | ],
386 | "description": "The composer plugin for Yii extension installer",
387 | "keywords": [
388 | "composer",
389 | "extension installer",
390 | "yii2"
391 | ],
392 | "time": "2016-02-06 00:49:24"
393 | }
394 | ],
395 | "packages-dev": [
396 | {
397 | "name": "doctrine/instantiator",
398 | "version": "1.0.5",
399 | "source": {
400 | "type": "git",
401 | "url": "https://github.com/doctrine/instantiator.git",
402 | "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d"
403 | },
404 | "dist": {
405 | "type": "zip",
406 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d",
407 | "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d",
408 | "shasum": ""
409 | },
410 | "require": {
411 | "php": ">=5.3,<8.0-DEV"
412 | },
413 | "require-dev": {
414 | "athletic/athletic": "~0.1.8",
415 | "ext-pdo": "*",
416 | "ext-phar": "*",
417 | "phpunit/phpunit": "~4.0",
418 | "squizlabs/php_codesniffer": "~2.0"
419 | },
420 | "type": "library",
421 | "extra": {
422 | "branch-alias": {
423 | "dev-master": "1.0.x-dev"
424 | }
425 | },
426 | "autoload": {
427 | "psr-4": {
428 | "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
429 | }
430 | },
431 | "notification-url": "https://packagist.org/downloads/",
432 | "license": [
433 | "MIT"
434 | ],
435 | "authors": [
436 | {
437 | "name": "Marco Pivetta",
438 | "email": "ocramius@gmail.com",
439 | "homepage": "http://ocramius.github.com/"
440 | }
441 | ],
442 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
443 | "homepage": "https://github.com/doctrine/instantiator",
444 | "keywords": [
445 | "constructor",
446 | "instantiate"
447 | ],
448 | "time": "2015-06-14 21:17:01"
449 | },
450 | {
451 | "name": "paulzi/yii2-adjacency-list",
452 | "version": "v2.0.3",
453 | "source": {
454 | "type": "git",
455 | "url": "https://github.com/paulzi/yii2-adjacency-list.git",
456 | "reference": "65da6ae0bc32211d7dbbf6df4f62526104116e4d"
457 | },
458 | "dist": {
459 | "type": "zip",
460 | "url": "https://api.github.com/repos/paulzi/yii2-adjacency-list/zipball/65da6ae0bc32211d7dbbf6df4f62526104116e4d",
461 | "reference": "65da6ae0bc32211d7dbbf6df4f62526104116e4d",
462 | "shasum": ""
463 | },
464 | "require": {
465 | "paulzi/yii2-sortable": "~1.0",
466 | "php": ">=5.4.0",
467 | "yiisoft/yii2": "~2.0.0"
468 | },
469 | "require-dev": {
470 | "phpunit/dbunit": "~1.0",
471 | "phpunit/phpunit": "~4.0"
472 | },
473 | "type": "yii2-extension",
474 | "autoload": {
475 | "psr-4": {
476 | "paulzi\\adjacencyList\\": ""
477 | }
478 | },
479 | "notification-url": "https://packagist.org/downloads/",
480 | "license": [
481 | "MIT"
482 | ],
483 | "authors": [
484 | {
485 | "name": "PaulZi",
486 | "email": "pavel.zimakoff@gmail.com"
487 | }
488 | ],
489 | "description": "Adjacency List Behavior for Yii2",
490 | "keywords": [
491 | "adjacency list",
492 | "yii2"
493 | ],
494 | "time": "2016-07-21 13:50:43"
495 | },
496 | {
497 | "name": "paulzi/yii2-materialized-path",
498 | "version": "v2.0.6",
499 | "source": {
500 | "type": "git",
501 | "url": "https://github.com/paulzi/yii2-materialized-path.git",
502 | "reference": "37135467e45209f3775fff0312f042a617da413c"
503 | },
504 | "dist": {
505 | "type": "zip",
506 | "url": "https://api.github.com/repos/paulzi/yii2-materialized-path/zipball/37135467e45209f3775fff0312f042a617da413c",
507 | "reference": "37135467e45209f3775fff0312f042a617da413c",
508 | "shasum": ""
509 | },
510 | "require": {
511 | "paulzi/yii2-sortable": "~1.0",
512 | "php": ">=5.4.0",
513 | "yiisoft/yii2": "~2.0.0"
514 | },
515 | "require-dev": {
516 | "phpunit/dbunit": "~1.0",
517 | "phpunit/phpunit": "~4.0"
518 | },
519 | "type": "yii2-extension",
520 | "autoload": {
521 | "psr-4": {
522 | "paulzi\\materializedPath\\": ""
523 | }
524 | },
525 | "notification-url": "https://packagist.org/downloads/",
526 | "license": [
527 | "MIT"
528 | ],
529 | "authors": [
530 | {
531 | "name": "PaulZi",
532 | "email": "pavel.zimakoff@gmail.com"
533 | }
534 | ],
535 | "description": "Materialized Path Behavior for Yii2",
536 | "keywords": [
537 | "materialized path",
538 | "yii2"
539 | ],
540 | "time": "2016-07-21 13:56:39"
541 | },
542 | {
543 | "name": "paulzi/yii2-nested-intervals",
544 | "version": "v1.0.5",
545 | "source": {
546 | "type": "git",
547 | "url": "https://github.com/paulzi/yii2-nested-intervals.git",
548 | "reference": "5a2aa28bc14b33f01c9fcbce85be20b5e49d0336"
549 | },
550 | "dist": {
551 | "type": "zip",
552 | "url": "https://api.github.com/repos/paulzi/yii2-nested-intervals/zipball/5a2aa28bc14b33f01c9fcbce85be20b5e49d0336",
553 | "reference": "5a2aa28bc14b33f01c9fcbce85be20b5e49d0336",
554 | "shasum": ""
555 | },
556 | "require": {
557 | "php": ">=5.4.0",
558 | "yiisoft/yii2": "~2.0.0"
559 | },
560 | "require-dev": {
561 | "phpunit/dbunit": "~1.0",
562 | "phpunit/phpunit": "~4.0"
563 | },
564 | "type": "yii2-extension",
565 | "autoload": {
566 | "psr-4": {
567 | "paulzi\\nestedintervals\\": ""
568 | }
569 | },
570 | "notification-url": "https://packagist.org/downloads/",
571 | "license": [
572 | "MIT"
573 | ],
574 | "authors": [
575 | {
576 | "name": "PaulZi",
577 | "email": "pavel.zimakoff@gmail.com"
578 | }
579 | ],
580 | "description": "Nested Intervals Behavior for Yii2",
581 | "keywords": [
582 | "nested intervals",
583 | "nested sets",
584 | "yii2"
585 | ],
586 | "time": "2016-07-21 14:01:31"
587 | },
588 | {
589 | "name": "paulzi/yii2-nested-sets",
590 | "version": "v1.0.4",
591 | "source": {
592 | "type": "git",
593 | "url": "https://github.com/paulzi/yii2-nested-sets.git",
594 | "reference": "d8350ad4b1a9fb38f990f5c30cf8f46fa9721e3c"
595 | },
596 | "dist": {
597 | "type": "zip",
598 | "url": "https://api.github.com/repos/paulzi/yii2-nested-sets/zipball/d8350ad4b1a9fb38f990f5c30cf8f46fa9721e3c",
599 | "reference": "d8350ad4b1a9fb38f990f5c30cf8f46fa9721e3c",
600 | "shasum": ""
601 | },
602 | "require": {
603 | "php": ">=5.4.0",
604 | "yiisoft/yii2": "~2.0.0"
605 | },
606 | "require-dev": {
607 | "phpunit/dbunit": "~1.0",
608 | "phpunit/phpunit": "~4.0"
609 | },
610 | "type": "yii2-extension",
611 | "autoload": {
612 | "psr-4": {
613 | "paulzi\\nestedsets\\": ""
614 | }
615 | },
616 | "notification-url": "https://packagist.org/downloads/",
617 | "license": [
618 | "MIT"
619 | ],
620 | "authors": [
621 | {
622 | "name": "Alexander Kochetov",
623 | "email": "creocoder@gmail.com"
624 | },
625 | {
626 | "name": "PaulZi",
627 | "email": "pavel.zimakoff@gmail.com"
628 | }
629 | ],
630 | "description": "Nested Sets Behavior for Yii2",
631 | "keywords": [
632 | "nested sets",
633 | "yii2"
634 | ],
635 | "time": "2016-07-21 13:59:00"
636 | },
637 | {
638 | "name": "paulzi/yii2-sortable",
639 | "version": "v1.0.0",
640 | "source": {
641 | "type": "git",
642 | "url": "https://github.com/paulzi/yii2-sortable.git",
643 | "reference": "7d42496f009ef935e25e6146e34d7d588f62610f"
644 | },
645 | "dist": {
646 | "type": "zip",
647 | "url": "https://api.github.com/repos/paulzi/yii2-sortable/zipball/7d42496f009ef935e25e6146e34d7d588f62610f",
648 | "reference": "7d42496f009ef935e25e6146e34d7d588f62610f",
649 | "shasum": ""
650 | },
651 | "require": {
652 | "php": ">=5.4.0",
653 | "yiisoft/yii2": "~2.0.0"
654 | },
655 | "require-dev": {
656 | "phpunit/dbunit": "~1.0",
657 | "phpunit/phpunit": "~4.0"
658 | },
659 | "type": "yii2-extension",
660 | "autoload": {
661 | "psr-4": {
662 | "paulzi\\sortable\\": ""
663 | }
664 | },
665 | "notification-url": "https://packagist.org/downloads/",
666 | "license": [
667 | "MIT"
668 | ],
669 | "authors": [
670 | {
671 | "name": "PaulZi",
672 | "email": "pavel.zimakoff@gmail.com"
673 | }
674 | ],
675 | "description": "Sortable Behavior for Yii2",
676 | "keywords": [
677 | "sortable",
678 | "yii2"
679 | ],
680 | "time": "2015-12-11 16:04:55"
681 | },
682 | {
683 | "name": "phpdocumentor/reflection-common",
684 | "version": "1.0",
685 | "source": {
686 | "type": "git",
687 | "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
688 | "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c"
689 | },
690 | "dist": {
691 | "type": "zip",
692 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/144c307535e82c8fdcaacbcfc1d6d8eeb896687c",
693 | "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c",
694 | "shasum": ""
695 | },
696 | "require": {
697 | "php": ">=5.5"
698 | },
699 | "require-dev": {
700 | "phpunit/phpunit": "^4.6"
701 | },
702 | "type": "library",
703 | "extra": {
704 | "branch-alias": {
705 | "dev-master": "1.0.x-dev"
706 | }
707 | },
708 | "autoload": {
709 | "psr-4": {
710 | "phpDocumentor\\Reflection\\": [
711 | "src"
712 | ]
713 | }
714 | },
715 | "notification-url": "https://packagist.org/downloads/",
716 | "license": [
717 | "MIT"
718 | ],
719 | "authors": [
720 | {
721 | "name": "Jaap van Otterdijk",
722 | "email": "opensource@ijaap.nl"
723 | }
724 | ],
725 | "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
726 | "homepage": "http://www.phpdoc.org",
727 | "keywords": [
728 | "FQSEN",
729 | "phpDocumentor",
730 | "phpdoc",
731 | "reflection",
732 | "static analysis"
733 | ],
734 | "time": "2015-12-27 11:43:31"
735 | },
736 | {
737 | "name": "phpdocumentor/reflection-docblock",
738 | "version": "3.1.0",
739 | "source": {
740 | "type": "git",
741 | "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
742 | "reference": "9270140b940ff02e58ec577c237274e92cd40cdd"
743 | },
744 | "dist": {
745 | "type": "zip",
746 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/9270140b940ff02e58ec577c237274e92cd40cdd",
747 | "reference": "9270140b940ff02e58ec577c237274e92cd40cdd",
748 | "shasum": ""
749 | },
750 | "require": {
751 | "php": ">=5.5",
752 | "phpdocumentor/reflection-common": "^1.0@dev",
753 | "phpdocumentor/type-resolver": "^0.2.0",
754 | "webmozart/assert": "^1.0"
755 | },
756 | "require-dev": {
757 | "mockery/mockery": "^0.9.4",
758 | "phpunit/phpunit": "^4.4"
759 | },
760 | "type": "library",
761 | "autoload": {
762 | "psr-4": {
763 | "phpDocumentor\\Reflection\\": [
764 | "src/"
765 | ]
766 | }
767 | },
768 | "notification-url": "https://packagist.org/downloads/",
769 | "license": [
770 | "MIT"
771 | ],
772 | "authors": [
773 | {
774 | "name": "Mike van Riel",
775 | "email": "me@mikevanriel.com"
776 | }
777 | ],
778 | "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
779 | "time": "2016-06-10 09:48:41"
780 | },
781 | {
782 | "name": "phpdocumentor/type-resolver",
783 | "version": "0.2",
784 | "source": {
785 | "type": "git",
786 | "url": "https://github.com/phpDocumentor/TypeResolver.git",
787 | "reference": "b39c7a5b194f9ed7bd0dd345c751007a41862443"
788 | },
789 | "dist": {
790 | "type": "zip",
791 | "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/b39c7a5b194f9ed7bd0dd345c751007a41862443",
792 | "reference": "b39c7a5b194f9ed7bd0dd345c751007a41862443",
793 | "shasum": ""
794 | },
795 | "require": {
796 | "php": ">=5.5",
797 | "phpdocumentor/reflection-common": "^1.0"
798 | },
799 | "require-dev": {
800 | "mockery/mockery": "^0.9.4",
801 | "phpunit/phpunit": "^5.2||^4.8.24"
802 | },
803 | "type": "library",
804 | "extra": {
805 | "branch-alias": {
806 | "dev-master": "1.0.x-dev"
807 | }
808 | },
809 | "autoload": {
810 | "psr-4": {
811 | "phpDocumentor\\Reflection\\": [
812 | "src/"
813 | ]
814 | }
815 | },
816 | "notification-url": "https://packagist.org/downloads/",
817 | "license": [
818 | "MIT"
819 | ],
820 | "authors": [
821 | {
822 | "name": "Mike van Riel",
823 | "email": "me@mikevanriel.com"
824 | }
825 | ],
826 | "time": "2016-06-10 07:14:17"
827 | },
828 | {
829 | "name": "phpspec/prophecy",
830 | "version": "v1.6.1",
831 | "source": {
832 | "type": "git",
833 | "url": "https://github.com/phpspec/prophecy.git",
834 | "reference": "58a8137754bc24b25740d4281399a4a3596058e0"
835 | },
836 | "dist": {
837 | "type": "zip",
838 | "url": "https://api.github.com/repos/phpspec/prophecy/zipball/58a8137754bc24b25740d4281399a4a3596058e0",
839 | "reference": "58a8137754bc24b25740d4281399a4a3596058e0",
840 | "shasum": ""
841 | },
842 | "require": {
843 | "doctrine/instantiator": "^1.0.2",
844 | "php": "^5.3|^7.0",
845 | "phpdocumentor/reflection-docblock": "^2.0|^3.0.2",
846 | "sebastian/comparator": "^1.1",
847 | "sebastian/recursion-context": "^1.0"
848 | },
849 | "require-dev": {
850 | "phpspec/phpspec": "^2.0"
851 | },
852 | "type": "library",
853 | "extra": {
854 | "branch-alias": {
855 | "dev-master": "1.6.x-dev"
856 | }
857 | },
858 | "autoload": {
859 | "psr-0": {
860 | "Prophecy\\": "src/"
861 | }
862 | },
863 | "notification-url": "https://packagist.org/downloads/",
864 | "license": [
865 | "MIT"
866 | ],
867 | "authors": [
868 | {
869 | "name": "Konstantin Kudryashov",
870 | "email": "ever.zet@gmail.com",
871 | "homepage": "http://everzet.com"
872 | },
873 | {
874 | "name": "Marcello Duarte",
875 | "email": "marcello.duarte@gmail.com"
876 | }
877 | ],
878 | "description": "Highly opinionated mocking framework for PHP 5.3+",
879 | "homepage": "https://github.com/phpspec/prophecy",
880 | "keywords": [
881 | "Double",
882 | "Dummy",
883 | "fake",
884 | "mock",
885 | "spy",
886 | "stub"
887 | ],
888 | "time": "2016-06-07 08:13:47"
889 | },
890 | {
891 | "name": "phpunit/dbunit",
892 | "version": "1.4.1",
893 | "source": {
894 | "type": "git",
895 | "url": "https://github.com/sebastianbergmann/dbunit.git",
896 | "reference": "9aaee6447663ff1b0cd50c23637e04af74c5e2ae"
897 | },
898 | "dist": {
899 | "type": "zip",
900 | "url": "https://api.github.com/repos/sebastianbergmann/dbunit/zipball/9aaee6447663ff1b0cd50c23637e04af74c5e2ae",
901 | "reference": "9aaee6447663ff1b0cd50c23637e04af74c5e2ae",
902 | "shasum": ""
903 | },
904 | "require": {
905 | "ext-pdo": "*",
906 | "ext-simplexml": "*",
907 | "php": ">=5.3.3",
908 | "phpunit/phpunit": "~4|~5",
909 | "symfony/yaml": "~2.1|~3.0"
910 | },
911 | "bin": [
912 | "composer/bin/dbunit"
913 | ],
914 | "type": "library",
915 | "extra": {
916 | "branch-alias": {
917 | "dev-master": "1.3.x-dev"
918 | }
919 | },
920 | "autoload": {
921 | "classmap": [
922 | "PHPUnit/"
923 | ]
924 | },
925 | "notification-url": "https://packagist.org/downloads/",
926 | "include-path": [
927 | "",
928 | "../../symfony/yaml/"
929 | ],
930 | "license": [
931 | "BSD-3-Clause"
932 | ],
933 | "authors": [
934 | {
935 | "name": "Sebastian Bergmann",
936 | "email": "sb@sebastian-bergmann.de",
937 | "role": "lead"
938 | }
939 | ],
940 | "description": "DbUnit port for PHP/PHPUnit to support database interaction testing.",
941 | "homepage": "https://github.com/sebastianbergmann/dbunit/",
942 | "keywords": [
943 | "database",
944 | "testing",
945 | "xunit"
946 | ],
947 | "time": "2015-08-07 04:57:38"
948 | },
949 | {
950 | "name": "phpunit/php-code-coverage",
951 | "version": "2.2.4",
952 | "source": {
953 | "type": "git",
954 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
955 | "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979"
956 | },
957 | "dist": {
958 | "type": "zip",
959 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979",
960 | "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979",
961 | "shasum": ""
962 | },
963 | "require": {
964 | "php": ">=5.3.3",
965 | "phpunit/php-file-iterator": "~1.3",
966 | "phpunit/php-text-template": "~1.2",
967 | "phpunit/php-token-stream": "~1.3",
968 | "sebastian/environment": "^1.3.2",
969 | "sebastian/version": "~1.0"
970 | },
971 | "require-dev": {
972 | "ext-xdebug": ">=2.1.4",
973 | "phpunit/phpunit": "~4"
974 | },
975 | "suggest": {
976 | "ext-dom": "*",
977 | "ext-xdebug": ">=2.2.1",
978 | "ext-xmlwriter": "*"
979 | },
980 | "type": "library",
981 | "extra": {
982 | "branch-alias": {
983 | "dev-master": "2.2.x-dev"
984 | }
985 | },
986 | "autoload": {
987 | "classmap": [
988 | "src/"
989 | ]
990 | },
991 | "notification-url": "https://packagist.org/downloads/",
992 | "license": [
993 | "BSD-3-Clause"
994 | ],
995 | "authors": [
996 | {
997 | "name": "Sebastian Bergmann",
998 | "email": "sb@sebastian-bergmann.de",
999 | "role": "lead"
1000 | }
1001 | ],
1002 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
1003 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
1004 | "keywords": [
1005 | "coverage",
1006 | "testing",
1007 | "xunit"
1008 | ],
1009 | "time": "2015-10-06 15:47:00"
1010 | },
1011 | {
1012 | "name": "phpunit/php-file-iterator",
1013 | "version": "1.4.1",
1014 | "source": {
1015 | "type": "git",
1016 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
1017 | "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0"
1018 | },
1019 | "dist": {
1020 | "type": "zip",
1021 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0",
1022 | "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0",
1023 | "shasum": ""
1024 | },
1025 | "require": {
1026 | "php": ">=5.3.3"
1027 | },
1028 | "type": "library",
1029 | "extra": {
1030 | "branch-alias": {
1031 | "dev-master": "1.4.x-dev"
1032 | }
1033 | },
1034 | "autoload": {
1035 | "classmap": [
1036 | "src/"
1037 | ]
1038 | },
1039 | "notification-url": "https://packagist.org/downloads/",
1040 | "license": [
1041 | "BSD-3-Clause"
1042 | ],
1043 | "authors": [
1044 | {
1045 | "name": "Sebastian Bergmann",
1046 | "email": "sb@sebastian-bergmann.de",
1047 | "role": "lead"
1048 | }
1049 | ],
1050 | "description": "FilterIterator implementation that filters files based on a list of suffixes.",
1051 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
1052 | "keywords": [
1053 | "filesystem",
1054 | "iterator"
1055 | ],
1056 | "time": "2015-06-21 13:08:43"
1057 | },
1058 | {
1059 | "name": "phpunit/php-text-template",
1060 | "version": "1.2.1",
1061 | "source": {
1062 | "type": "git",
1063 | "url": "https://github.com/sebastianbergmann/php-text-template.git",
1064 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
1065 | },
1066 | "dist": {
1067 | "type": "zip",
1068 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
1069 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
1070 | "shasum": ""
1071 | },
1072 | "require": {
1073 | "php": ">=5.3.3"
1074 | },
1075 | "type": "library",
1076 | "autoload": {
1077 | "classmap": [
1078 | "src/"
1079 | ]
1080 | },
1081 | "notification-url": "https://packagist.org/downloads/",
1082 | "license": [
1083 | "BSD-3-Clause"
1084 | ],
1085 | "authors": [
1086 | {
1087 | "name": "Sebastian Bergmann",
1088 | "email": "sebastian@phpunit.de",
1089 | "role": "lead"
1090 | }
1091 | ],
1092 | "description": "Simple template engine.",
1093 | "homepage": "https://github.com/sebastianbergmann/php-text-template/",
1094 | "keywords": [
1095 | "template"
1096 | ],
1097 | "time": "2015-06-21 13:50:34"
1098 | },
1099 | {
1100 | "name": "phpunit/php-timer",
1101 | "version": "1.0.8",
1102 | "source": {
1103 | "type": "git",
1104 | "url": "https://github.com/sebastianbergmann/php-timer.git",
1105 | "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260"
1106 | },
1107 | "dist": {
1108 | "type": "zip",
1109 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/38e9124049cf1a164f1e4537caf19c99bf1eb260",
1110 | "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260",
1111 | "shasum": ""
1112 | },
1113 | "require": {
1114 | "php": ">=5.3.3"
1115 | },
1116 | "require-dev": {
1117 | "phpunit/phpunit": "~4|~5"
1118 | },
1119 | "type": "library",
1120 | "autoload": {
1121 | "classmap": [
1122 | "src/"
1123 | ]
1124 | },
1125 | "notification-url": "https://packagist.org/downloads/",
1126 | "license": [
1127 | "BSD-3-Clause"
1128 | ],
1129 | "authors": [
1130 | {
1131 | "name": "Sebastian Bergmann",
1132 | "email": "sb@sebastian-bergmann.de",
1133 | "role": "lead"
1134 | }
1135 | ],
1136 | "description": "Utility class for timing",
1137 | "homepage": "https://github.com/sebastianbergmann/php-timer/",
1138 | "keywords": [
1139 | "timer"
1140 | ],
1141 | "time": "2016-05-12 18:03:57"
1142 | },
1143 | {
1144 | "name": "phpunit/php-token-stream",
1145 | "version": "1.4.8",
1146 | "source": {
1147 | "type": "git",
1148 | "url": "https://github.com/sebastianbergmann/php-token-stream.git",
1149 | "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da"
1150 | },
1151 | "dist": {
1152 | "type": "zip",
1153 | "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da",
1154 | "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da",
1155 | "shasum": ""
1156 | },
1157 | "require": {
1158 | "ext-tokenizer": "*",
1159 | "php": ">=5.3.3"
1160 | },
1161 | "require-dev": {
1162 | "phpunit/phpunit": "~4.2"
1163 | },
1164 | "type": "library",
1165 | "extra": {
1166 | "branch-alias": {
1167 | "dev-master": "1.4-dev"
1168 | }
1169 | },
1170 | "autoload": {
1171 | "classmap": [
1172 | "src/"
1173 | ]
1174 | },
1175 | "notification-url": "https://packagist.org/downloads/",
1176 | "license": [
1177 | "BSD-3-Clause"
1178 | ],
1179 | "authors": [
1180 | {
1181 | "name": "Sebastian Bergmann",
1182 | "email": "sebastian@phpunit.de"
1183 | }
1184 | ],
1185 | "description": "Wrapper around PHP's tokenizer extension.",
1186 | "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
1187 | "keywords": [
1188 | "tokenizer"
1189 | ],
1190 | "time": "2015-09-15 10:49:45"
1191 | },
1192 | {
1193 | "name": "phpunit/phpunit",
1194 | "version": "4.8.27",
1195 | "source": {
1196 | "type": "git",
1197 | "url": "https://github.com/sebastianbergmann/phpunit.git",
1198 | "reference": "c062dddcb68e44b563f66ee319ddae2b5a322a90"
1199 | },
1200 | "dist": {
1201 | "type": "zip",
1202 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c062dddcb68e44b563f66ee319ddae2b5a322a90",
1203 | "reference": "c062dddcb68e44b563f66ee319ddae2b5a322a90",
1204 | "shasum": ""
1205 | },
1206 | "require": {
1207 | "ext-dom": "*",
1208 | "ext-json": "*",
1209 | "ext-pcre": "*",
1210 | "ext-reflection": "*",
1211 | "ext-spl": "*",
1212 | "php": ">=5.3.3",
1213 | "phpspec/prophecy": "^1.3.1",
1214 | "phpunit/php-code-coverage": "~2.1",
1215 | "phpunit/php-file-iterator": "~1.4",
1216 | "phpunit/php-text-template": "~1.2",
1217 | "phpunit/php-timer": "^1.0.6",
1218 | "phpunit/phpunit-mock-objects": "~2.3",
1219 | "sebastian/comparator": "~1.1",
1220 | "sebastian/diff": "~1.2",
1221 | "sebastian/environment": "~1.3",
1222 | "sebastian/exporter": "~1.2",
1223 | "sebastian/global-state": "~1.0",
1224 | "sebastian/version": "~1.0",
1225 | "symfony/yaml": "~2.1|~3.0"
1226 | },
1227 | "suggest": {
1228 | "phpunit/php-invoker": "~1.1"
1229 | },
1230 | "bin": [
1231 | "phpunit"
1232 | ],
1233 | "type": "library",
1234 | "extra": {
1235 | "branch-alias": {
1236 | "dev-master": "4.8.x-dev"
1237 | }
1238 | },
1239 | "autoload": {
1240 | "classmap": [
1241 | "src/"
1242 | ]
1243 | },
1244 | "notification-url": "https://packagist.org/downloads/",
1245 | "license": [
1246 | "BSD-3-Clause"
1247 | ],
1248 | "authors": [
1249 | {
1250 | "name": "Sebastian Bergmann",
1251 | "email": "sebastian@phpunit.de",
1252 | "role": "lead"
1253 | }
1254 | ],
1255 | "description": "The PHP Unit Testing framework.",
1256 | "homepage": "https://phpunit.de/",
1257 | "keywords": [
1258 | "phpunit",
1259 | "testing",
1260 | "xunit"
1261 | ],
1262 | "time": "2016-07-21 06:48:14"
1263 | },
1264 | {
1265 | "name": "phpunit/phpunit-mock-objects",
1266 | "version": "2.3.8",
1267 | "source": {
1268 | "type": "git",
1269 | "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
1270 | "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983"
1271 | },
1272 | "dist": {
1273 | "type": "zip",
1274 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983",
1275 | "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983",
1276 | "shasum": ""
1277 | },
1278 | "require": {
1279 | "doctrine/instantiator": "^1.0.2",
1280 | "php": ">=5.3.3",
1281 | "phpunit/php-text-template": "~1.2",
1282 | "sebastian/exporter": "~1.2"
1283 | },
1284 | "require-dev": {
1285 | "phpunit/phpunit": "~4.4"
1286 | },
1287 | "suggest": {
1288 | "ext-soap": "*"
1289 | },
1290 | "type": "library",
1291 | "extra": {
1292 | "branch-alias": {
1293 | "dev-master": "2.3.x-dev"
1294 | }
1295 | },
1296 | "autoload": {
1297 | "classmap": [
1298 | "src/"
1299 | ]
1300 | },
1301 | "notification-url": "https://packagist.org/downloads/",
1302 | "license": [
1303 | "BSD-3-Clause"
1304 | ],
1305 | "authors": [
1306 | {
1307 | "name": "Sebastian Bergmann",
1308 | "email": "sb@sebastian-bergmann.de",
1309 | "role": "lead"
1310 | }
1311 | ],
1312 | "description": "Mock Object library for PHPUnit",
1313 | "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
1314 | "keywords": [
1315 | "mock",
1316 | "xunit"
1317 | ],
1318 | "time": "2015-10-02 06:51:40"
1319 | },
1320 | {
1321 | "name": "sebastian/comparator",
1322 | "version": "1.2.0",
1323 | "source": {
1324 | "type": "git",
1325 | "url": "https://github.com/sebastianbergmann/comparator.git",
1326 | "reference": "937efb279bd37a375bcadf584dec0726f84dbf22"
1327 | },
1328 | "dist": {
1329 | "type": "zip",
1330 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22",
1331 | "reference": "937efb279bd37a375bcadf584dec0726f84dbf22",
1332 | "shasum": ""
1333 | },
1334 | "require": {
1335 | "php": ">=5.3.3",
1336 | "sebastian/diff": "~1.2",
1337 | "sebastian/exporter": "~1.2"
1338 | },
1339 | "require-dev": {
1340 | "phpunit/phpunit": "~4.4"
1341 | },
1342 | "type": "library",
1343 | "extra": {
1344 | "branch-alias": {
1345 | "dev-master": "1.2.x-dev"
1346 | }
1347 | },
1348 | "autoload": {
1349 | "classmap": [
1350 | "src/"
1351 | ]
1352 | },
1353 | "notification-url": "https://packagist.org/downloads/",
1354 | "license": [
1355 | "BSD-3-Clause"
1356 | ],
1357 | "authors": [
1358 | {
1359 | "name": "Jeff Welch",
1360 | "email": "whatthejeff@gmail.com"
1361 | },
1362 | {
1363 | "name": "Volker Dusch",
1364 | "email": "github@wallbash.com"
1365 | },
1366 | {
1367 | "name": "Bernhard Schussek",
1368 | "email": "bschussek@2bepublished.at"
1369 | },
1370 | {
1371 | "name": "Sebastian Bergmann",
1372 | "email": "sebastian@phpunit.de"
1373 | }
1374 | ],
1375 | "description": "Provides the functionality to compare PHP values for equality",
1376 | "homepage": "http://www.github.com/sebastianbergmann/comparator",
1377 | "keywords": [
1378 | "comparator",
1379 | "compare",
1380 | "equality"
1381 | ],
1382 | "time": "2015-07-26 15:48:44"
1383 | },
1384 | {
1385 | "name": "sebastian/diff",
1386 | "version": "1.4.1",
1387 | "source": {
1388 | "type": "git",
1389 | "url": "https://github.com/sebastianbergmann/diff.git",
1390 | "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e"
1391 | },
1392 | "dist": {
1393 | "type": "zip",
1394 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e",
1395 | "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e",
1396 | "shasum": ""
1397 | },
1398 | "require": {
1399 | "php": ">=5.3.3"
1400 | },
1401 | "require-dev": {
1402 | "phpunit/phpunit": "~4.8"
1403 | },
1404 | "type": "library",
1405 | "extra": {
1406 | "branch-alias": {
1407 | "dev-master": "1.4-dev"
1408 | }
1409 | },
1410 | "autoload": {
1411 | "classmap": [
1412 | "src/"
1413 | ]
1414 | },
1415 | "notification-url": "https://packagist.org/downloads/",
1416 | "license": [
1417 | "BSD-3-Clause"
1418 | ],
1419 | "authors": [
1420 | {
1421 | "name": "Kore Nordmann",
1422 | "email": "mail@kore-nordmann.de"
1423 | },
1424 | {
1425 | "name": "Sebastian Bergmann",
1426 | "email": "sebastian@phpunit.de"
1427 | }
1428 | ],
1429 | "description": "Diff implementation",
1430 | "homepage": "https://github.com/sebastianbergmann/diff",
1431 | "keywords": [
1432 | "diff"
1433 | ],
1434 | "time": "2015-12-08 07:14:41"
1435 | },
1436 | {
1437 | "name": "sebastian/environment",
1438 | "version": "1.3.7",
1439 | "source": {
1440 | "type": "git",
1441 | "url": "https://github.com/sebastianbergmann/environment.git",
1442 | "reference": "4e8f0da10ac5802913afc151413bc8c53b6c2716"
1443 | },
1444 | "dist": {
1445 | "type": "zip",
1446 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/4e8f0da10ac5802913afc151413bc8c53b6c2716",
1447 | "reference": "4e8f0da10ac5802913afc151413bc8c53b6c2716",
1448 | "shasum": ""
1449 | },
1450 | "require": {
1451 | "php": ">=5.3.3"
1452 | },
1453 | "require-dev": {
1454 | "phpunit/phpunit": "~4.4"
1455 | },
1456 | "type": "library",
1457 | "extra": {
1458 | "branch-alias": {
1459 | "dev-master": "1.3.x-dev"
1460 | }
1461 | },
1462 | "autoload": {
1463 | "classmap": [
1464 | "src/"
1465 | ]
1466 | },
1467 | "notification-url": "https://packagist.org/downloads/",
1468 | "license": [
1469 | "BSD-3-Clause"
1470 | ],
1471 | "authors": [
1472 | {
1473 | "name": "Sebastian Bergmann",
1474 | "email": "sebastian@phpunit.de"
1475 | }
1476 | ],
1477 | "description": "Provides functionality to handle HHVM/PHP environments",
1478 | "homepage": "http://www.github.com/sebastianbergmann/environment",
1479 | "keywords": [
1480 | "Xdebug",
1481 | "environment",
1482 | "hhvm"
1483 | ],
1484 | "time": "2016-05-17 03:18:57"
1485 | },
1486 | {
1487 | "name": "sebastian/exporter",
1488 | "version": "1.2.2",
1489 | "source": {
1490 | "type": "git",
1491 | "url": "https://github.com/sebastianbergmann/exporter.git",
1492 | "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4"
1493 | },
1494 | "dist": {
1495 | "type": "zip",
1496 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4",
1497 | "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4",
1498 | "shasum": ""
1499 | },
1500 | "require": {
1501 | "php": ">=5.3.3",
1502 | "sebastian/recursion-context": "~1.0"
1503 | },
1504 | "require-dev": {
1505 | "ext-mbstring": "*",
1506 | "phpunit/phpunit": "~4.4"
1507 | },
1508 | "type": "library",
1509 | "extra": {
1510 | "branch-alias": {
1511 | "dev-master": "1.3.x-dev"
1512 | }
1513 | },
1514 | "autoload": {
1515 | "classmap": [
1516 | "src/"
1517 | ]
1518 | },
1519 | "notification-url": "https://packagist.org/downloads/",
1520 | "license": [
1521 | "BSD-3-Clause"
1522 | ],
1523 | "authors": [
1524 | {
1525 | "name": "Jeff Welch",
1526 | "email": "whatthejeff@gmail.com"
1527 | },
1528 | {
1529 | "name": "Volker Dusch",
1530 | "email": "github@wallbash.com"
1531 | },
1532 | {
1533 | "name": "Bernhard Schussek",
1534 | "email": "bschussek@2bepublished.at"
1535 | },
1536 | {
1537 | "name": "Sebastian Bergmann",
1538 | "email": "sebastian@phpunit.de"
1539 | },
1540 | {
1541 | "name": "Adam Harvey",
1542 | "email": "aharvey@php.net"
1543 | }
1544 | ],
1545 | "description": "Provides the functionality to export PHP variables for visualization",
1546 | "homepage": "http://www.github.com/sebastianbergmann/exporter",
1547 | "keywords": [
1548 | "export",
1549 | "exporter"
1550 | ],
1551 | "time": "2016-06-17 09:04:28"
1552 | },
1553 | {
1554 | "name": "sebastian/global-state",
1555 | "version": "1.1.1",
1556 | "source": {
1557 | "type": "git",
1558 | "url": "https://github.com/sebastianbergmann/global-state.git",
1559 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4"
1560 | },
1561 | "dist": {
1562 | "type": "zip",
1563 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4",
1564 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4",
1565 | "shasum": ""
1566 | },
1567 | "require": {
1568 | "php": ">=5.3.3"
1569 | },
1570 | "require-dev": {
1571 | "phpunit/phpunit": "~4.2"
1572 | },
1573 | "suggest": {
1574 | "ext-uopz": "*"
1575 | },
1576 | "type": "library",
1577 | "extra": {
1578 | "branch-alias": {
1579 | "dev-master": "1.0-dev"
1580 | }
1581 | },
1582 | "autoload": {
1583 | "classmap": [
1584 | "src/"
1585 | ]
1586 | },
1587 | "notification-url": "https://packagist.org/downloads/",
1588 | "license": [
1589 | "BSD-3-Clause"
1590 | ],
1591 | "authors": [
1592 | {
1593 | "name": "Sebastian Bergmann",
1594 | "email": "sebastian@phpunit.de"
1595 | }
1596 | ],
1597 | "description": "Snapshotting of global state",
1598 | "homepage": "http://www.github.com/sebastianbergmann/global-state",
1599 | "keywords": [
1600 | "global state"
1601 | ],
1602 | "time": "2015-10-12 03:26:01"
1603 | },
1604 | {
1605 | "name": "sebastian/recursion-context",
1606 | "version": "1.0.2",
1607 | "source": {
1608 | "type": "git",
1609 | "url": "https://github.com/sebastianbergmann/recursion-context.git",
1610 | "reference": "913401df809e99e4f47b27cdd781f4a258d58791"
1611 | },
1612 | "dist": {
1613 | "type": "zip",
1614 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/913401df809e99e4f47b27cdd781f4a258d58791",
1615 | "reference": "913401df809e99e4f47b27cdd781f4a258d58791",
1616 | "shasum": ""
1617 | },
1618 | "require": {
1619 | "php": ">=5.3.3"
1620 | },
1621 | "require-dev": {
1622 | "phpunit/phpunit": "~4.4"
1623 | },
1624 | "type": "library",
1625 | "extra": {
1626 | "branch-alias": {
1627 | "dev-master": "1.0.x-dev"
1628 | }
1629 | },
1630 | "autoload": {
1631 | "classmap": [
1632 | "src/"
1633 | ]
1634 | },
1635 | "notification-url": "https://packagist.org/downloads/",
1636 | "license": [
1637 | "BSD-3-Clause"
1638 | ],
1639 | "authors": [
1640 | {
1641 | "name": "Jeff Welch",
1642 | "email": "whatthejeff@gmail.com"
1643 | },
1644 | {
1645 | "name": "Sebastian Bergmann",
1646 | "email": "sebastian@phpunit.de"
1647 | },
1648 | {
1649 | "name": "Adam Harvey",
1650 | "email": "aharvey@php.net"
1651 | }
1652 | ],
1653 | "description": "Provides functionality to recursively process PHP variables",
1654 | "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
1655 | "time": "2015-11-11 19:50:13"
1656 | },
1657 | {
1658 | "name": "sebastian/version",
1659 | "version": "1.0.6",
1660 | "source": {
1661 | "type": "git",
1662 | "url": "https://github.com/sebastianbergmann/version.git",
1663 | "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6"
1664 | },
1665 | "dist": {
1666 | "type": "zip",
1667 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
1668 | "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
1669 | "shasum": ""
1670 | },
1671 | "type": "library",
1672 | "autoload": {
1673 | "classmap": [
1674 | "src/"
1675 | ]
1676 | },
1677 | "notification-url": "https://packagist.org/downloads/",
1678 | "license": [
1679 | "BSD-3-Clause"
1680 | ],
1681 | "authors": [
1682 | {
1683 | "name": "Sebastian Bergmann",
1684 | "email": "sebastian@phpunit.de",
1685 | "role": "lead"
1686 | }
1687 | ],
1688 | "description": "Library that helps with managing the version number of Git-hosted PHP projects",
1689 | "homepage": "https://github.com/sebastianbergmann/version",
1690 | "time": "2015-06-21 13:59:46"
1691 | },
1692 | {
1693 | "name": "symfony/yaml",
1694 | "version": "v3.1.2",
1695 | "source": {
1696 | "type": "git",
1697 | "url": "https://github.com/symfony/yaml.git",
1698 | "reference": "2884c26ce4c1d61aebf423a8b912950fe7c764de"
1699 | },
1700 | "dist": {
1701 | "type": "zip",
1702 | "url": "https://api.github.com/repos/symfony/yaml/zipball/2884c26ce4c1d61aebf423a8b912950fe7c764de",
1703 | "reference": "2884c26ce4c1d61aebf423a8b912950fe7c764de",
1704 | "shasum": ""
1705 | },
1706 | "require": {
1707 | "php": ">=5.5.9"
1708 | },
1709 | "type": "library",
1710 | "extra": {
1711 | "branch-alias": {
1712 | "dev-master": "3.1-dev"
1713 | }
1714 | },
1715 | "autoload": {
1716 | "psr-4": {
1717 | "Symfony\\Component\\Yaml\\": ""
1718 | },
1719 | "exclude-from-classmap": [
1720 | "/Tests/"
1721 | ]
1722 | },
1723 | "notification-url": "https://packagist.org/downloads/",
1724 | "license": [
1725 | "MIT"
1726 | ],
1727 | "authors": [
1728 | {
1729 | "name": "Fabien Potencier",
1730 | "email": "fabien@symfony.com"
1731 | },
1732 | {
1733 | "name": "Symfony Community",
1734 | "homepage": "https://symfony.com/contributors"
1735 | }
1736 | ],
1737 | "description": "Symfony Yaml Component",
1738 | "homepage": "https://symfony.com",
1739 | "time": "2016-06-29 05:41:56"
1740 | },
1741 | {
1742 | "name": "webmozart/assert",
1743 | "version": "1.0.2",
1744 | "source": {
1745 | "type": "git",
1746 | "url": "https://github.com/webmozart/assert.git",
1747 | "reference": "30eed06dd6bc88410a4ff7f77b6d22f3ce13dbde"
1748 | },
1749 | "dist": {
1750 | "type": "zip",
1751 | "url": "https://api.github.com/repos/webmozart/assert/zipball/30eed06dd6bc88410a4ff7f77b6d22f3ce13dbde",
1752 | "reference": "30eed06dd6bc88410a4ff7f77b6d22f3ce13dbde",
1753 | "shasum": ""
1754 | },
1755 | "require": {
1756 | "php": ">=5.3.3"
1757 | },
1758 | "require-dev": {
1759 | "phpunit/phpunit": "^4.6"
1760 | },
1761 | "type": "library",
1762 | "extra": {
1763 | "branch-alias": {
1764 | "dev-master": "1.0-dev"
1765 | }
1766 | },
1767 | "autoload": {
1768 | "psr-4": {
1769 | "Webmozart\\Assert\\": "src/"
1770 | }
1771 | },
1772 | "notification-url": "https://packagist.org/downloads/",
1773 | "license": [
1774 | "MIT"
1775 | ],
1776 | "authors": [
1777 | {
1778 | "name": "Bernhard Schussek",
1779 | "email": "bschussek@gmail.com"
1780 | }
1781 | ],
1782 | "description": "Assertions to validate method input/output with nice error messages.",
1783 | "keywords": [
1784 | "assert",
1785 | "check",
1786 | "validate"
1787 | ],
1788 | "time": "2015-08-24 13:29:44"
1789 | }
1790 | ],
1791 | "aliases": [],
1792 | "minimum-stability": "stable",
1793 | "stability-flags": [],
1794 | "prefer-stable": false,
1795 | "prefer-lowest": false,
1796 | "platform": {
1797 | "php": ">=5.4.0"
1798 | },
1799 | "platform-dev": []
1800 | }
1801 |
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 | ./tests
11 |
12 |
13 |
--------------------------------------------------------------------------------
/tests/.gitignore:
--------------------------------------------------------------------------------
1 | /data/config.local.php
--------------------------------------------------------------------------------
/tests/AlMpTest.php:
--------------------------------------------------------------------------------
1 |
5 | * @license MIT (https://github.com/paulzi/yii2-auto-tree/blob/master/LICENSE)
6 | */
7 |
8 | namespace paulzi\autotree\tests;
9 |
10 | use paulzi\autotree\tests\models\NodeAlMp;
11 | use Yii;
12 |
13 | /**
14 | * @author PaulZi
15 | * @group AlMp
16 | */
17 | class AlMpTest extends AutoTreeTraitTestCase
18 | {
19 | public function getModelClass()
20 | {
21 | return NodeAlMp::className();
22 | }
23 |
24 | public function testMakeRootInsert()
25 | {
26 | $node = new NodeAlMp(['slug' => 'r']);
27 | $this->assertTrue($node->makeRoot()->save());
28 |
29 | $node->refresh();
30 | $this->assertEquals(null, $node->parent_id);
31 | $this->assertEquals(0, $node->sort);
32 | $this->assertEquals(0, $node->depth);
33 | }
34 |
35 | public function testMakeRootUpdate()
36 | {
37 | $node = NodeAlMp::findOne(9);
38 | $this->assertTrue($node->makeRoot()->save());
39 |
40 | $node->refresh();
41 | $this->assertEquals(null, $node->parent_id);
42 | $this->assertEquals(0, $node->sort);
43 | $this->assertEquals(0, $node->depth);
44 | }
45 |
46 | public function testPrependTo()
47 | {
48 | $node = new NodeAlMp(['slug' => 'new']);
49 | $this->assertTrue($node->prependTo(NodeAlMp::findOne(1))->save());
50 |
51 | $node->refresh();
52 | $this->assertEquals(1, $node->parent_id);
53 | $this->assertEquals(-101, $node->sort);
54 | $this->assertEquals(1, $node->depth);
55 | }
56 |
57 | public function testPrependToAnotherTree()
58 | {
59 | $node = NodeAlMp::findOne(30);
60 | $this->assertTrue($node->prependTo(NodeAlMp::findOne(4))->save());
61 |
62 | $node->refresh();
63 | $this->assertEquals(4, $node->parent_id);
64 | $this->assertEquals(-100, $node->sort);
65 | $this->assertEquals(2, $node->depth);
66 | }
67 |
68 | public function testAppendTo()
69 | {
70 | $node = NodeAlMp::findOne(10);
71 | $this->assertTrue($node->appendTo(NodeAlMp::findOne(18))->save());
72 |
73 | $node->refresh();
74 | $this->assertEquals(18, $node->parent_id);
75 | $this->assertEquals(0, $node->sort);
76 | $this->assertEquals(4, $node->depth);
77 | }
78 |
79 | public function testInsertBefore()
80 | {
81 | $node = new NodeAlMp(['slug' => 'new']);
82 | $this->assertTrue($node->insertBefore(NodeAlMp::findOne(22))->save());
83 |
84 | $node->refresh();
85 | $this->assertEquals(9, $node->parent_id);
86 | $this->assertEquals(3, $node->sort);
87 | $this->assertEquals(3, $node->depth);
88 | }
89 |
90 | public function testInsertAfter()
91 | {
92 | $node = NodeAlMp::findOne(32);
93 | $this->assertTrue($node->insertAfter(NodeAlMp::findOne(30))->save());
94 |
95 | $node->refresh();
96 | $this->assertEquals(26, $node->parent_id);
97 | $this->assertEquals(3, $node->sort);
98 | $this->assertEquals(1, $node->depth);
99 | }
100 |
101 | public function testInsertAfterAnotherTree()
102 | {
103 | $node = NodeAlMp::findOne(26);
104 | $this->assertTrue($node->insertAfter(NodeAlMp::findOne(21))->save());
105 |
106 | $node->refresh();
107 | $this->assertEquals(9, $node->parent_id);
108 | $this->assertEquals(3, $node->sort);
109 | $this->assertEquals(3, $node->depth);
110 | }
111 |
112 | public function testDelete()
113 | {
114 | $this->assertEquals(1, NodeAlMp::findOne(30)->delete());
115 | $this->assertEquals(null, NodeAlMp::findOne(30));
116 | }
117 |
118 | public function testDeleteWithChildren()
119 | {
120 | $this->assertEquals(10, NodeAlMp::findOne(4)->deleteWithChildren());
121 | $this->assertEquals(null, NodeAlMp::findOne(24));
122 | $this->assertEquals(15, NodeAlMp::findOne(1)->deleteWithChildren());
123 | }
124 | }
--------------------------------------------------------------------------------
/tests/AlNiTest.php:
--------------------------------------------------------------------------------
1 |
5 | * @license MIT (https://github.com/paulzi/yii2-auto-tree/blob/master/LICENSE)
6 | */
7 |
8 | namespace paulzi\autotree\tests;
9 |
10 | use paulzi\autotree\tests\models\NodeAlNi;
11 | use Yii;
12 |
13 | /**
14 | * @author PaulZi
15 | * @group AlNi
16 | */
17 | class AlNiTest extends AutoTreeTraitTestCase
18 | {
19 | /**
20 | * @inheritdoc
21 | */
22 | public function getDataSet()
23 | {
24 | return new \PHPUnit_Extensions_Database_DataSet_ArrayDataSet(require(__DIR__ . '/data/data-ni.php'));
25 | }
26 |
27 | public function getModelClass()
28 | {
29 | return NodeAlNi::className();
30 | }
31 |
32 | public function testMakeRootInsert()
33 | {
34 | $node = new NodeAlNi(['slug' => 'r']);
35 | $this->assertTrue($node->makeRoot()->save());
36 |
37 | $node->refresh();
38 | $this->assertEquals(null, $node->parent_id);
39 | $this->assertEquals(0, $node->lft);
40 | $this->assertEquals(2147483647, $node->rgt);
41 | $this->assertEquals(0, $node->depth);
42 | }
43 |
44 | public function testMakeRootUpdate()
45 | {
46 | $node = NodeAlNi::findOne(9);
47 | $this->assertTrue($node->makeRoot()->save());
48 |
49 | $node->refresh();
50 | $this->assertEquals(null, $node->parent_id);
51 | $this->assertEquals(0, $node->lft);
52 | $this->assertEquals(2147483647, $node->rgt);
53 | $this->assertEquals(0, $node->depth);
54 | }
55 |
56 | public function testPrependTo()
57 | {
58 | $node = new NodeAlNi(['slug' => 'new']);
59 | $this->assertTrue($node->prependTo(NodeAlNi::findOne(1))->save());
60 |
61 | $node->refresh();
62 | $this->assertEquals(1, $node->parent_id);
63 | $this->assertEquals(1, $node->lft);
64 | $this->assertEquals(2, $node->rgt);
65 | $this->assertEquals(1, $node->depth);
66 | }
67 |
68 | public function testPrependToAnotherTree()
69 | {
70 | $node = NodeAlNi::findOne(30);
71 | $this->assertTrue($node->prependTo(NodeAlNi::findOne(4))->save());
72 |
73 | $node->refresh();
74 | $this->assertEquals(4, $node->parent_id);
75 | $this->assertEquals(1091940810, $node->lft);
76 | $this->assertEquals(1419523107, $node->rgt);
77 | $this->assertEquals(2, $node->depth);
78 | }
79 |
80 | public function testAppendTo()
81 | {
82 | $node = NodeAlNi::findOne(10);
83 | $this->assertTrue($node->appendTo(NodeAlNi::findOne(18))->save());
84 |
85 | $node->refresh();
86 | $this->assertEquals(18, $node->parent_id);
87 | $this->assertEquals(1000013, $node->lft);
88 | $this->assertEquals(1000024, $node->rgt);
89 | $this->assertEquals(4, $node->depth);
90 | }
91 |
92 | public function testInsertBefore()
93 | {
94 | $node = new NodeAlNi(['slug' => 'new']);
95 | $this->assertTrue($node->insertBefore(NodeAlNi::findOne(22))->save());
96 |
97 | $node->refresh();
98 | $this->assertEquals(9, $node->parent_id);
99 | $this->assertEquals(300000005, $node->lft);
100 | $this->assertEquals(300000006, $node->rgt);
101 | $this->assertEquals(3, $node->depth);
102 | }
103 |
104 | public function testInsertAfter()
105 | {
106 | $node = NodeAlNi::findOne(32);
107 | $this->assertTrue($node->insertAfter(NodeAlNi::findOne(30))->save());
108 |
109 | $node->refresh();
110 | $this->assertEquals(26, $node->parent_id);
111 | $this->assertEquals(2147483644, $node->lft);
112 | $this->assertEquals(2147483646, $node->rgt);
113 | $this->assertEquals(1, $node->depth);
114 | }
115 |
116 | public function testInsertAfterAnotherTree()
117 | {
118 | $node = NodeAlNi::findOne(26);
119 | $this->assertTrue($node->insertAfter(NodeAlNi::findOne(21))->save());
120 |
121 | $node->refresh();
122 | $this->assertEquals(9, $node->parent_id);
123 | $this->assertEquals(1031907726, $node->lft);
124 | $this->assertEquals(1784921473, $node->rgt);
125 | $this->assertEquals(3, $node->depth);
126 | }
127 |
128 | public function testDelete()
129 | {
130 | $this->assertEquals(1, NodeAlNi::findOne(30)->delete());
131 | $this->assertEquals(null, NodeAlNi::findOne(30));
132 | }
133 |
134 | public function testDeleteWithChildren()
135 | {
136 | $this->assertEquals(10, NodeAlNi::findOne(4)->deleteWithChildren());
137 | $this->assertEquals(null, NodeAlNi::findOne(24));
138 | $this->assertEquals(15, NodeAlNi::findOne(1)->deleteWithChildren());
139 | }
140 | }
--------------------------------------------------------------------------------
/tests/AlNsTest.php:
--------------------------------------------------------------------------------
1 |
5 | * @license MIT (https://github.com/paulzi/yii2-auto-tree/blob/master/LICENSE)
6 | */
7 |
8 | namespace paulzi\autotree\tests;
9 |
10 | use paulzi\autotree\tests\models\NodeAlNs;
11 | use Yii;
12 |
13 | /**
14 | * @author PaulZi
15 | * @group AlNs
16 | */
17 | class AlNsTest extends AutoTreeTraitTestCase
18 | {
19 | public function getModelClass()
20 | {
21 | return NodeAlNs::className();
22 | }
23 |
24 | public function testMakeRootInsert()
25 | {
26 | $node = new NodeAlNs(['slug' => 'r']);
27 | $this->assertTrue($node->makeRoot()->save());
28 |
29 | $node->refresh();
30 | $this->assertEquals(null, $node->parent_id);
31 | $this->assertEquals(1, $node->lft);
32 | $this->assertEquals(2, $node->rgt);
33 | $this->assertEquals(0, $node->depth);
34 | }
35 |
36 | public function testMakeRootUpdate()
37 | {
38 | $node = NodeAlNs::findOne(9);
39 | $this->assertTrue($node->makeRoot()->save());
40 |
41 | $node->refresh();
42 | $this->assertEquals(null, $node->parent_id);
43 | $this->assertEquals(1, $node->lft);
44 | $this->assertEquals(8, $node->rgt);
45 | $this->assertEquals(0, $node->depth);
46 | }
47 |
48 | public function testPrependTo()
49 | {
50 | $node = new NodeAlNs(['slug' => 'new']);
51 | $this->assertTrue($node->prependTo(NodeAlNs::findOne(1))->save());
52 |
53 | $node->refresh();
54 | $this->assertEquals(1, $node->parent_id);
55 | $this->assertEquals(2, $node->lft);
56 | $this->assertEquals(3, $node->rgt);
57 | $this->assertEquals(1, $node->depth);
58 | }
59 |
60 | public function testPrependToAnotherTree()
61 | {
62 | $node = NodeAlNs::findOne(30);
63 | $this->assertTrue($node->prependTo(NodeAlNs::findOne(4))->save());
64 |
65 | $node->refresh();
66 | $this->assertEquals(4, $node->parent_id);
67 | $this->assertEquals(31, $node->lft);
68 | $this->assertEquals(40, $node->rgt);
69 | $this->assertEquals(2, $node->depth);
70 | }
71 |
72 | public function testAppendTo()
73 | {
74 | $node = NodeAlNs::findOne(10);
75 | $this->assertTrue($node->appendTo(NodeAlNs::findOne(18))->save());
76 |
77 | $node->refresh();
78 | $this->assertEquals(18, $node->parent_id);
79 | $this->assertEquals(23, $node->lft);
80 | $this->assertEquals(30, $node->rgt);
81 | $this->assertEquals(4, $node->depth);
82 | }
83 |
84 | public function testInsertBefore()
85 | {
86 | $node = new NodeAlNs(['slug' => 'new']);
87 | $this->assertTrue($node->insertBefore(NodeAlNs::findOne(22))->save());
88 |
89 | $node->refresh();
90 | $this->assertEquals(9, $node->parent_id);
91 | $this->assertEquals(38, $node->lft);
92 | $this->assertEquals(39, $node->rgt);
93 | $this->assertEquals(3, $node->depth);
94 | }
95 |
96 | public function testInsertAfter()
97 | {
98 | $node = NodeAlNs::findOne(32);
99 | $this->assertTrue($node->insertAfter(NodeAlNs::findOne(30))->save());
100 |
101 | $node->refresh();
102 | $this->assertEquals(26, $node->parent_id);
103 | $this->assertEquals(26, $node->lft);
104 | $this->assertEquals(27, $node->rgt);
105 | $this->assertEquals(1, $node->depth);
106 | }
107 |
108 | public function testInsertAfterAnotherTree()
109 | {
110 | $node = NodeAlNs::findOne(26);
111 | $this->assertTrue($node->insertAfter(NodeAlNs::findOne(21))->save());
112 |
113 | $node->refresh();
114 | $this->assertEquals(9, $node->parent_id);
115 | $this->assertEquals(38, $node->lft);
116 | $this->assertEquals(65, $node->rgt);
117 | $this->assertEquals(3, $node->depth);
118 | }
119 |
120 | public function testDelete()
121 | {
122 | $this->assertEquals(1, NodeAlNs::findOne(30)->delete());
123 | $this->assertEquals(null, NodeAlNs::findOne(30));
124 | }
125 |
126 | public function testDeleteWithChildren()
127 | {
128 | $this->assertEquals(10, NodeAlNs::findOne(4)->deleteWithChildren());
129 | $this->assertEquals(null, NodeAlNs::findOne(24));
130 | $this->assertEquals(15, NodeAlNs::findOne(1)->deleteWithChildren());
131 | }
132 | }
--------------------------------------------------------------------------------
/tests/ArrayDataSet.php:
--------------------------------------------------------------------------------
1 |
5 | * @license MIT (https://github.com/paulzi/yii2-auto-tree/blob/master/LICENSE)
6 | */
7 |
8 | namespace paulzi\autotree\tests;
9 |
10 | /**
11 | * @author PaulZi
12 | */
13 | class ArrayDataSet extends \PHPUnit_Extensions_Database_DataSet_ArrayDataSet
14 | {
15 | public function __construct(array $data)
16 | {
17 | foreach ($data as $tableName => $rows) {
18 | $columns = array();
19 | if (isset($rows['columns'])) {
20 | $columns = $rows['columns'];
21 | unset($rows['columns']);
22 | } elseif (isset($rows[0])) {
23 | $columns = array_keys($rows[0]);
24 | }
25 |
26 | $metaData = new \PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData($tableName, $columns);
27 | $table = new \PHPUnit_Extensions_Database_DataSet_DefaultTable($metaData);
28 |
29 | foreach ($rows AS $row) {
30 | $table->addRow($row);
31 | }
32 | $this->tables[$tableName] = $table;
33 | }
34 | }
35 | }
--------------------------------------------------------------------------------
/tests/AutoTreeTraitTestCase.php:
--------------------------------------------------------------------------------
1 |
5 | * @license MIT (https://github.com/paulzi/yii2-auto-tree/blob/master/LICENSE)
6 | */
7 |
8 | namespace paulzi\autotree\tests;
9 |
10 | use Yii;
11 |
12 | /**
13 | * @author PaulZi
14 | */
15 | class AutoTreeTraitTestCase extends BaseTestCase
16 | {
17 | /**
18 | * @return \yii\db\BaseActiveRecord
19 | */
20 | public function getModelClass()
21 | {
22 | return null;
23 | }
24 |
25 | public function testGetParents()
26 | {
27 | $modelClass = $this->getModelClass();
28 |
29 | $data = [1, 4, 9];
30 | $this->assertEquals($data, array_map(function ($value) { return $value->id; }, $modelClass::findOne(21)->parents));
31 |
32 | $data = [];
33 | $this->assertEquals($data, array_map(function ($value) { return $value->id; }, $modelClass::findOne(1)->parents));
34 |
35 | $data = [2, 7];
36 | $this->assertEquals($data, array_map(function ($value) { return $value->id; }, $modelClass::findOne(17)->getParents(2)->all()));
37 |
38 | $data = [26, 30];
39 | $this->assertEquals($data, array_map(function ($value) { return $value->id; }, $modelClass::findOne(38)->parents));
40 | }
41 |
42 | public function testGetParent()
43 | {
44 | $modelClass = $this->getModelClass();
45 | $this->assertEquals(5, $modelClass::findOne(12)->parent->id);
46 | $this->assertEquals(26, $modelClass::findOne(29)->getParent()->one()->getAttribute('id'));
47 | $this->assertEquals(null, $modelClass::findOne(1)->parent);
48 | }
49 |
50 | public function testGetRoot()
51 | {
52 | $modelClass = $this->getModelClass();
53 | $this->assertEquals(26, $modelClass::findOne(28)->root->id);
54 | $this->assertEquals(26, $modelClass::findOne(26)->getRoot()->one()->getAttribute('id'));
55 | }
56 |
57 | public function testGetDescendants()
58 | {
59 | $modelClass = $this->getModelClass();
60 |
61 | $data = [8, 9, 10, 20, 21, 22, 23, 24, 25];
62 | $data2 = array_map(function ($value) { return $value->id; }, $modelClass::findOne(4)->descendants);
63 | sort($data2);
64 | $this->assertEquals($data, $data2);
65 |
66 | $data = [2, 5, 6, 7];
67 | $data2 = array_map(function ($value) { return $value->id; }, $modelClass::findOne(2)->getDescendants(1, true)->all());
68 | sort($data2);
69 | $this->assertEquals($data, $data2);
70 |
71 | $data = [];
72 | $this->assertEquals($data, array_map(function ($value) { return $value->id; }, $modelClass::findOne(8)->descendants));
73 | }
74 |
75 | public function testGetChildren()
76 | {
77 | $modelClass = $this->getModelClass();
78 |
79 | $data = [8, 9, 10];
80 | $this->assertEquals($data, array_map(function ($value) { return $value->id; }, $modelClass::findOne(4)->children));
81 |
82 | $data = [];
83 | $this->assertEquals($data, array_map(function ($value) { return $value->id; }, $modelClass::findOne(28)->getChildren()->all()));
84 | }
85 |
86 | public function testGetLeaves()
87 | {
88 | $modelClass = $this->getModelClass();
89 |
90 | $data = [8, 20, 21, 22, 23, 24, 25];
91 | $this->assertEquals($data, array_map(function ($value) { return $value->id; }, $modelClass::findOne(4)->leaves));
92 |
93 | $data = [3, 8];
94 | $this->assertEquals($data, array_map(function ($value) { return $value->id; }, $modelClass::findOne(1)->getLeaves(2)->all()));
95 | }
96 |
97 | public function testGetPrev()
98 | {
99 | $modelClass = $this->getModelClass();
100 | $this->assertEquals(11, $modelClass::findOne(12)->prev->id);
101 | $this->assertEquals(null, $modelClass::findOne(20)->getPrev()->one());
102 | }
103 |
104 | public function testGetNext()
105 | {
106 | $modelClass = $this->getModelClass();
107 | $this->assertEquals(13, $modelClass::findOne(12)->next->id);
108 | $this->assertEquals(null, $modelClass::findOne(19)->getNext()->one());
109 | }
110 |
111 | public function testIsRoot()
112 | {
113 | $modelClass = $this->getModelClass();
114 | $this->assertTrue($modelClass::findOne(1)->isRoot());
115 | $this->assertTrue($modelClass::findOne(26)->isRoot());
116 | $this->assertFalse($modelClass::findOne(3)->isRoot());
117 | $this->assertFalse($modelClass::findOne(37)->isRoot());
118 | }
119 |
120 | public function testIsChildOf()
121 | {
122 | $modelClass = $this->getModelClass();
123 | $this->assertTrue($modelClass::findOne(10)->isChildOf($modelClass::findOne(1)));
124 | $this->assertTrue($modelClass::findOne(9)->isChildOf($modelClass::findOne(4)));
125 | $this->assertFalse($modelClass::findOne(12)->isChildOf($modelClass::findOne(15)));
126 | $this->assertFalse($modelClass::findOne(21)->isChildOf($modelClass::findOne(22)));
127 | $this->assertFalse($modelClass::findOne(8)->isChildOf($modelClass::findOne(8)));
128 | $this->assertFalse($modelClass::findOne(6)->isChildOf($modelClass::findOne(27)));
129 | }
130 |
131 | public function testIsLeaf()
132 | {
133 | $modelClass = $this->getModelClass();
134 | $this->assertTrue($modelClass::findOne(3)->isLeaf());
135 | $this->assertFalse($modelClass::findOne(4)->isLeaf());
136 | }
137 | }
--------------------------------------------------------------------------------
/tests/BaseTestCase.php:
--------------------------------------------------------------------------------
1 |
5 | * @license MIT (https://github.com/paulzi/yii2-auto-tree/blob/master/LICENSE)
6 | */
7 |
8 | namespace paulzi\autotree\tests;
9 |
10 | use paulzi\autotree\tests\migrations\TestMigration;
11 | use Yii;
12 | use yii\db\Connection;
13 |
14 | /**
15 | * @author PaulZi
16 | */
17 | class BaseTestCase extends \PHPUnit_Extensions_Database_TestCase
18 | {
19 | protected static $driverName = 'sqlite';
20 |
21 |
22 | /**
23 | * @inheritdoc
24 | */
25 | public function getConnection()
26 | {
27 | return $this->createDefaultDBConnection(Yii::$app->getDb()->pdo);
28 | }
29 |
30 | /**
31 | * @inheritdoc
32 | */
33 | public function getDataSet()
34 | {
35 | return new \PHPUnit_Extensions_Database_DataSet_ArrayDataSet(require(__DIR__ . '/data/data.php'));
36 | }
37 |
38 | /**
39 | * @inheritdoc
40 | */
41 | protected function setUp()
42 | {
43 | if (Yii::$app->get('db', false) === null) {
44 | $this->markTestSkipped();
45 | } else {
46 | (new TestMigration())->up();
47 | parent::setUp();
48 | }
49 | }
50 |
51 | /**
52 | * @inheritdoc
53 | */
54 | public static function setUpBeforeClass()
55 | {
56 | $config = require(__DIR__ . '/data/config.php');
57 | $config = $config[static::$driverName];
58 | $config['class'] = Connection::className();
59 | try {
60 | Yii::$app->set('db', $config);
61 | Yii::$app->getDb()->open();
62 | } catch (\Exception $e) {
63 | Yii::$app->clear('db');
64 | }
65 | }
66 | }
--------------------------------------------------------------------------------
/tests/README.md:
--------------------------------------------------------------------------------
1 | # Yii2 Auto Tree Trait unit tests
2 |
3 | ## How to run the test
4 |
5 | Make sure you have PHPUnit installed and that you installed all composer dependencies (run `composer update` in the repo base directory).
6 |
7 | Run PHPUnit in the yii repo base directory.
8 |
9 | ```
10 | phpunit
11 | ```
12 |
13 | You can run tests for specific groups only:
14 |
15 | ```
16 | phpunit --group=AiNs
17 | ```
18 |
19 | You can get a list of available groups via `phpunit --list-groups`.
20 |
21 | ## test configurations
22 |
23 | PHPUnit configuration is in `phpunit.xml.dist` in repository root folder.
24 | You can create your own phpunit.xml to override dist config.
25 |
26 | Database and other backend system configuration can be found in `tests/data/config.php`
27 | adjust them to your needs to allow testing databases and caching in your environment.
28 | You can override configuration values by creating a `config.local.php` file
29 | and manipulate the `$config` variable.
30 | For example to change MySQL username and password your `config.local.php` should
31 | contain the following:
32 |
33 | ```php
34 |
5 | * @license MIT (https://github.com/paulzi/yii2-auto-tree/blob/master/LICENSE)
6 | */
7 |
8 | defined('YII_DEBUG') or define('YII_DEBUG', true);
9 | defined('YII_ENV') or define('YII_ENV', 'test');
10 |
11 | require(__DIR__ . '/../vendor/autoload.php');
12 | require(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php');
13 |
14 | Yii::setAlias('@tests', __DIR__);
15 |
16 | new \yii\console\Application([
17 | 'id' => 'unit',
18 | 'basePath' => __DIR__,
19 | ]);
--------------------------------------------------------------------------------
/tests/data/config.php:
--------------------------------------------------------------------------------
1 | [
4 | 'dsn' => 'sqlite::memory:',
5 | ],
6 | 'mysql' => [
7 | 'dsn' => 'mysql:host=localhost;dbname=test',
8 | 'username' => 'root',
9 | 'password' => '',
10 | 'charset' => 'utf8',
11 | ],
12 | 'mssql' => [
13 | 'dsn' => 'sqlsrv:Server=localhost;Database=test',
14 | 'username' => '',
15 | 'password' => '',
16 | ],
17 | 'pgsql' => [
18 | 'dsn' => 'pgsql:host=localhost;dbname=test;port=5432;',
19 | 'username' => 'postgres',
20 | 'password' => 'postgres',
21 | ],
22 | ];
23 |
24 | if (is_file(__DIR__ . '/config.local.php')) {
25 | include(__DIR__ . '/config.local.php');
26 | }
27 |
28 | return $config;
--------------------------------------------------------------------------------
/tests/data/data-ni.php:
--------------------------------------------------------------------------------
1 | array(
4 | array('id' => '1','parent_id' => null,'sort' => '0', 'tree' => '1','lft' => '0','rgt' => '2147483647','depth' => '0','path' => '1','slug' => 'r1'),
5 | array('id' => '2','parent_id' => '1','sort' => '-1','tree' => '1','lft' => '1','rgt' => '1000021','depth' => '1','path' => '1/2','slug' => 'n1'),
6 | array('id' => '3','parent_id' => '1','sort' => '0','tree' => '1','lft' => '10000000','rgt' => '20000000','depth' => '1','path' => '1/3','slug' => 'n2'),
7 | array('id' => '4','parent_id' => '1','sort' => '1','tree' => '1','lft' => '100000000','rgt' => '1987654321','depth' => '1','path' => '1/4','slug' => 'n3'),
8 | array('id' => '5','parent_id' => '2','sort' => '0','tree' => '1','lft' => '2','rgt' => '30002','depth' => '2','path' => '1/2/5','slug' => 'n11'),
9 | array('id' => '6','parent_id' => '2','sort' => '100','tree' => '1','lft' => '30003','rgt' => '1000000','depth' => '2','path' => '1/2/6','slug' => 'n12'),
10 | array('id' => '7','parent_id' => '2','sort' => '200','tree' => '1','lft' => '1000001','rgt' => '1000020','depth' => '2','path' => '1/2/7','slug' => 'n13'),
11 | array('id' => '8','parent_id' => '4','sort' => '0','tree' => '1','lft' => '200000000','rgt' => '200000002','depth' => '2','path' => '1/4/8','slug' => 'n31'),
12 | array('id' => '9','parent_id' => '4','sort' => '1','tree' => '1','lft' => '300000000','rgt' => '300000007','depth' => '2','path' => '1/4/9','slug' => 'n32'),
13 | array('id' => '10','parent_id' => '4','sort' => '100','tree' => '1','lft' => '1234567890','rgt' => '1234567901','depth' => '2','path' => '1/4/10','slug' => 'n33'),
14 | array('id' => '11','parent_id' => '5','sort' => '0','tree' => '1','lft' => '3','rgt' => '4','depth' => '3','path' => '1/2/5/11','slug' => 'n111'),
15 | array('id' => '12','parent_id' => '5','sort' => '99','tree' => '1','lft' => '10000','rgt' => '20000','depth' => '3','path' => '1/2/5/12','slug' => 'n112'),
16 | array('id' => '13','parent_id' => '5','sort' => '100','tree' => '1','lft' => '20001','rgt' => '30000','depth' => '3','path' => '1/2/5/13','slug' => 'n113'),
17 | array('id' => '14','parent_id' => '6','sort' => '-100','tree' => '1','lft' => '444444','rgt' => '444544','depth' => '3','path' => '1/2/6/14','slug' => 'n121'),
18 | array('id' => '15','parent_id' => '6','sort' => '-99','tree' => '1','lft' => '666666','rgt' => '777777','depth' => '3','path' => '1/2/6/15','slug' => 'n122'),
19 | array('id' => '16','parent_id' => '6','sort' => '-98','tree' => '1','lft' => '888888','rgt' => '888898','depth' => '3','path' => '1/2/6/16','slug' => 'n123'),
20 | array('id' => '17','parent_id' => '7','sort' => '-100','tree' => '1','lft' => '1000004','rgt' => '1000007','depth' => '3','path' => '1/2/7/17','slug' => 'n131'),
21 | array('id' => '18','parent_id' => '7','sort' => '0','tree' => '1','lft' => '1000010','rgt' => '1000013','depth' => '3','path' => '1/2/7/18','slug' => 'n132'),
22 | array('id' => '19','parent_id' => '7','sort' => '100','tree' => '1','lft' => '1000016','rgt' => '1000019','depth' => '3','path' => '1/2/7/19','slug' => 'n133'),
23 | array('id' => '20','parent_id' => '9','sort' => '0','tree' => '1','lft' => '300000001','rgt' => '300000002','depth' => '3','path' => '1/4/9/20','slug' => 'n321'),
24 | array('id' => '21','parent_id' => '9','sort' => '2','tree' => '1','lft' => '300000003','rgt' => '300000004','depth' => '3','path' => '1/4/9/21','slug' => 'n322'),
25 | array('id' => '22','parent_id' => '9','sort' => '4','tree' => '1','lft' => '300000005','rgt' => '300000006','depth' => '3','path' => '1/4/9/22','slug' => 'n323'),
26 | array('id' => '23','parent_id' => '10','sort' => '0','tree' => '1','lft' => '1234567892','rgt' => '1234567893','depth' => '3','path' => '1/4/10/23','slug' => 'n331'),
27 | array('id' => '24','parent_id' => '10','sort' => '100','tree' => '1','lft' => '1234567895','rgt' => '1234567896','depth' => '3','path' => '1/4/10/24','slug' => 'n332'),
28 | array('id' => '25','parent_id' => '10','sort' => '200','tree' => '1','lft' => '1234567898','rgt' => '1234567899','depth' => '3','path' => '1/4/10/25','slug' => 'n333'),
29 |
30 | array('id' => '26','parent_id' => null,'sort' => '0','tree' => '26','lft' => '0','rgt' => '2147483647','depth' => '0','path' => '26','slug' => 'r2'),
31 | array('id' => '27','parent_id' => '26','sort' => '-1','tree' => '26','lft' => '10000','rgt' => '10018','depth' => '1','path' => '26/27','slug' => 'n1'),
32 | array('id' => '28','parent_id' => '26','sort' => '0','tree' => '26','lft' => '2323287','rgt' => '2323288','depth' => '1','path' => '26/28','slug' => 'n2'),
33 | array('id' => '29','parent_id' => '26','sort' => '1','tree' => '26','lft' => '72938298','rgt' => '72938302','depth' => '1','path' => '26/29','slug' => 'n3'),
34 | array('id' => '30','parent_id' => '26','sort' => '2','tree' => '26','lft' => '2039849384','rgt' => '2147483646','depth' => '1','path' => '26/30','slug' => 'n4'),
35 | array('id' => '31','parent_id' => '27','sort' => '0','tree' => '26','lft' => '10002','rgt' => '10004','depth' => '2','path' => '26/27/31','slug' => 'n11'),
36 | array('id' => '32','parent_id' => '27','sort' => '1','tree' => '26','lft' => '10006','rgt' => '10008','depth' => '2','path' => '26/27/32','slug' => 'n12'),
37 | array('id' => '33','parent_id' => '27','sort' => '2','tree' => '26','lft' => '10010','rgt' => '10012','depth' => '2','path' => '26/27/33','slug' => 'n13'),
38 | array('id' => '34','parent_id' => '27','sort' => '4','tree' => '26','lft' => '10014','rgt' => '10016','depth' => '2','path' => '26/27/34','slug' => 'n14'),
39 | array('id' => '35','parent_id' => '29','sort' => '0','tree' => '26','lft' => '72938299','rgt' => '72938301','depth' => '2','path' => '26/29/35','slug' => 'n31'),
40 | array('id' => '36','parent_id' => '30','sort' => '0','tree' => '26','lft' => '2147483637','rgt' => '2147483638','depth' => '2','path' => '26/30/36','slug' => 'n41'),
41 | array('id' => '37','parent_id' => '30','sort' => '100','tree' => '26','lft' => '2147483639','rgt' => '2147483640','depth' => '2','path' => '26/30/36','slug' => 'n42'),
42 | array('id' => '38','parent_id' => '30','sort' => '200','tree' => '26','lft' => '2147483642','rgt' => '2147483643','depth' => '2','path' => '26/30/36','slug' => 'n43'),
43 | array('id' => '39','parent_id' => '30','sort' => '300','tree' => '26','lft' => '2147483644','rgt' => '2147483645','depth' => '2','path' => '26/30/36','slug' => 'n44'),
44 | ),
45 | );
--------------------------------------------------------------------------------
/tests/data/data.php:
--------------------------------------------------------------------------------
1 | array(
4 | array('id' => '1','parent_id' => null,'sort' => '0', 'tree' => '1','lft' => '1','rgt' => '50','depth' => '0','path' => '1','slug' => 'r1'),
5 | array('id' => '2','parent_id' => '1','sort' => '-1','tree' => '1','lft' => '2','rgt' => '27','depth' => '1','path' => '1/2','slug' => 'n1'),
6 | array('id' => '3','parent_id' => '1','sort' => '0','tree' => '1','lft' => '28','rgt' => '29','depth' => '1','path' => '1/3','slug' => 'n2'),
7 | array('id' => '4','parent_id' => '1','sort' => '1','tree' => '1','lft' => '30','rgt' => '49','depth' => '1','path' => '1/4','slug' => 'n3'),
8 | array('id' => '5','parent_id' => '2','sort' => '0','tree' => '1','lft' => '3','rgt' => '10','depth' => '2','path' => '1/2/5','slug' => 'n11'),
9 | array('id' => '6','parent_id' => '2','sort' => '100','tree' => '1','lft' => '11','rgt' => '18','depth' => '2','path' => '1/2/6','slug' => 'n12'),
10 | array('id' => '7','parent_id' => '2','sort' => '200','tree' => '1','lft' => '19','rgt' => '26','depth' => '2','path' => '1/2/7','slug' => 'n13'),
11 | array('id' => '8','parent_id' => '4','sort' => '0','tree' => '1','lft' => '31','rgt' => '32','depth' => '2','path' => '1/4/8','slug' => 'n31'),
12 | array('id' => '9','parent_id' => '4','sort' => '1','tree' => '1','lft' => '33','rgt' => '40','depth' => '2','path' => '1/4/9','slug' => 'n32'),
13 | array('id' => '10','parent_id' => '4','sort' => '100','tree' => '1','lft' => '41','rgt' => '48','depth' => '2','path' => '1/4/10','slug' => 'n33'),
14 | array('id' => '11','parent_id' => '5','sort' => '0','tree' => '1','lft' => '4','rgt' => '5','depth' => '3','path' => '1/2/5/11','slug' => 'n111'),
15 | array('id' => '12','parent_id' => '5','sort' => '99','tree' => '1','lft' => '6','rgt' => '7','depth' => '3','path' => '1/2/5/12','slug' => 'n112'),
16 | array('id' => '13','parent_id' => '5','sort' => '100','tree' => '1','lft' => '8','rgt' => '9','depth' => '3','path' => '1/2/5/13','slug' => 'n113'),
17 | array('id' => '14','parent_id' => '6','sort' => '-100','tree' => '1','lft' => '12','rgt' => '13','depth' => '3','path' => '1/2/6/14','slug' => 'n121'),
18 | array('id' => '15','parent_id' => '6','sort' => '-99','tree' => '1','lft' => '14','rgt' => '15','depth' => '3','path' => '1/2/6/15','slug' => 'n122'),
19 | array('id' => '16','parent_id' => '6','sort' => '-98','tree' => '1','lft' => '16','rgt' => '17','depth' => '3','path' => '1/2/6/16','slug' => 'n123'),
20 | array('id' => '17','parent_id' => '7','sort' => '-100','tree' => '1','lft' => '20','rgt' => '21','depth' => '3','path' => '1/2/7/17','slug' => 'n131'),
21 | array('id' => '18','parent_id' => '7','sort' => '0','tree' => '1','lft' => '22','rgt' => '23','depth' => '3','path' => '1/2/7/18','slug' => 'n132'),
22 | array('id' => '19','parent_id' => '7','sort' => '100','tree' => '1','lft' => '24','rgt' => '25','depth' => '3','path' => '1/2/7/19','slug' => 'n133'),
23 | array('id' => '20','parent_id' => '9','sort' => '0','tree' => '1','lft' => '34','rgt' => '35','depth' => '3','path' => '1/4/9/20','slug' => 'n321'),
24 | array('id' => '21','parent_id' => '9','sort' => '2','tree' => '1','lft' => '36','rgt' => '37','depth' => '3','path' => '1/4/9/21','slug' => 'n322'),
25 | array('id' => '22','parent_id' => '9','sort' => '4','tree' => '1','lft' => '38','rgt' => '39','depth' => '3','path' => '1/4/9/22','slug' => 'n323'),
26 | array('id' => '23','parent_id' => '10','sort' => '0','tree' => '1','lft' => '42','rgt' => '43','depth' => '3','path' => '1/4/10/23','slug' => 'n331'),
27 | array('id' => '24','parent_id' => '10','sort' => '100','tree' => '1','lft' => '44','rgt' => '45','depth' => '3','path' => '1/4/10/24','slug' => 'n332'),
28 | array('id' => '25','parent_id' => '10','sort' => '200','tree' => '1','lft' => '46','rgt' => '47','depth' => '3','path' => '1/4/10/25','slug' => 'n333'),
29 |
30 | array('id' => '26','parent_id' => null,'sort' => '0','tree' => '26','lft' => '1','rgt' => '28','depth' => '0','path' => '26','slug' => 'r2'),
31 | array('id' => '27','parent_id' => '26','sort' => '-1','tree' => '26','lft' => '2','rgt' => '11','depth' => '1','path' => '26/27','slug' => 'n1'),
32 | array('id' => '28','parent_id' => '26','sort' => '0','tree' => '26','lft' => '12','rgt' => '13','depth' => '1','path' => '26/28','slug' => 'n2'),
33 | array('id' => '29','parent_id' => '26','sort' => '1','tree' => '26','lft' => '14','rgt' => '17','depth' => '1','path' => '26/29','slug' => 'n3'),
34 | array('id' => '30','parent_id' => '26','sort' => '2','tree' => '26','lft' => '18','rgt' => '27','depth' => '1','path' => '26/30','slug' => 'n4'),
35 | array('id' => '31','parent_id' => '27','sort' => '0','tree' => '26','lft' => '3','rgt' => '4','depth' => '2','path' => '26/27/31','slug' => 'n11'),
36 | array('id' => '32','parent_id' => '27','sort' => '1','tree' => '26','lft' => '5','rgt' => '6','depth' => '2','path' => '26/27/32','slug' => 'n12'),
37 | array('id' => '33','parent_id' => '27','sort' => '2','tree' => '26','lft' => '7','rgt' => '8','depth' => '2','path' => '26/27/33','slug' => 'n13'),
38 | array('id' => '34','parent_id' => '27','sort' => '4','tree' => '26','lft' => '9','rgt' => '10','depth' => '2','path' => '26/27/34','slug' => 'n14'),
39 | array('id' => '35','parent_id' => '29','sort' => '0','tree' => '26','lft' => '15','rgt' => '16','depth' => '2','path' => '26/29/35','slug' => 'n31'),
40 | array('id' => '36','parent_id' => '30','sort' => '0','tree' => '26','lft' => '19','rgt' => '20','depth' => '2','path' => '26/30/36','slug' => 'n41'),
41 | array('id' => '37','parent_id' => '30','sort' => '100','tree' => '26','lft' => '21','rgt' => '22','depth' => '2','path' => '26/30/36','slug' => 'n42'),
42 | array('id' => '38','parent_id' => '30','sort' => '200','tree' => '26','lft' => '23','rgt' => '24','depth' => '2','path' => '26/30/36','slug' => 'n43'),
43 | array('id' => '39','parent_id' => '30','sort' => '300','tree' => '26','lft' => '25','rgt' => '26','depth' => '2','path' => '26/30/36','slug' => 'n44'),
44 | ),
45 | );
--------------------------------------------------------------------------------
/tests/migrations/TestMigration.php:
--------------------------------------------------------------------------------
1 |
5 | * @license MIT (https://github.com/paulzi/yii2-auto-tree/blob/master/LICENSE)
6 | */
7 |
8 | namespace paulzi\autotree\tests\migrations;
9 |
10 | use yii\db\Schema;
11 | use yii\db\Migration;
12 |
13 | /**
14 | * @author PaulZi
15 | */
16 | class TestMigration extends Migration
17 | {
18 | public function up()
19 | {
20 | ob_start();
21 | $tableOptions = null;
22 | if ($this->db->driverName === 'mysql') {
23 | // http://stackoverflow.com/questions/766809/whats-the-difference-between-utf8-general-ci-and-utf8-unicode-ci
24 | $tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB';
25 | }
26 |
27 | if ($this->db->getTableSchema('{{%tree}}', true) !== null) {
28 | $this->dropTable('{{%tree}}');
29 | }
30 | $this->createTable('{{%tree}}', [
31 | 'id' => Schema::TYPE_PK,
32 | 'parent_id' => Schema::TYPE_INTEGER . ' NULL',
33 | 'sort' => Schema::TYPE_INTEGER . ' NULL',
34 | 'tree' => Schema::TYPE_INTEGER . ' NULL',
35 | 'lft' => Schema::TYPE_INTEGER . ' NULL',
36 | 'rgt' => Schema::TYPE_INTEGER . ' NULL',
37 | 'depth' => Schema::TYPE_INTEGER . ' NULL',
38 | 'path' => Schema::TYPE_STRING . ' NULL',
39 | 'slug' => Schema::TYPE_STRING . ' NOT NULL',
40 | ], $tableOptions);
41 | $this->createIndex('parent_sort', '{{%tree}}', ['parent_id', 'sort']);
42 | $this->createIndex('lft', '{{%tree}}', ['tree', 'lft', 'rgt']);
43 | $this->createIndex('rgt', '{{%tree}}', ['tree', 'rgt']);
44 | $this->createIndex('path', '{{%tree}}', ['tree', 'path']);
45 |
46 | // update cache (sqlite bug)
47 | $this->db->getSchema()->getTableSchema('{{%tree}}', true);
48 | ob_end_clean();
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/tests/models/NodeAlMp.php:
--------------------------------------------------------------------------------
1 |
5 | * @license MIT (https://github.com/paulzi/yii2-auto-tree/blob/master/LICENSE)
6 | */
7 |
8 | namespace paulzi\autotree\tests\models;
9 |
10 | use paulzi\adjacencyList\AdjacencyListBehavior;
11 | use paulzi\materializedPath\MaterializedPathBehavior;
12 | use paulzi\autotree\AutoTreeTrait;
13 |
14 | /**
15 | * @author PaulZi
16 | *
17 | * @property integer $id
18 | * @property integer $parent_id
19 | * @property integer $sort
20 | * @property integer $tree
21 | * @property integer $lft
22 | * @property integer $rgt
23 | * @property integer $depth
24 | * @property string $path
25 | * @property string $slug
26 | *
27 | * @property NodeAlMp[] $parents
28 | * @property NodeAlMp $parent
29 | * @property NodeAlMp $root
30 | * @property NodeAlMp[] $descendants
31 | * @property NodeAlMp[] $children
32 | * @property NodeAlMp[] $leaves
33 | * @property NodeAlMp $prev
34 | * @property NodeAlMp $next
35 | *
36 | * @method static NodeAlMp|null findOne() findOne($condition)
37 | *
38 | * @mixin AdjacencyListBehavior
39 | * @mixin MaterializedPathBehavior
40 | */
41 | class NodeAlMp extends \yii\db\ActiveRecord
42 | {
43 | use AutoTreeTrait;
44 |
45 | /**
46 | * @inheritdoc
47 | */
48 | public static function tableName()
49 | {
50 | return '{{%tree}}';
51 | }
52 | /**
53 | * @inheritdoc
54 | */
55 | public function behaviors()
56 | {
57 | return [
58 | [
59 | 'class' => AdjacencyListBehavior::className(),
60 | 'sortable' => false,
61 | ],
62 | [
63 | 'class' => MaterializedPathBehavior::className(),
64 | ],
65 | ];
66 | }
67 |
68 | /**
69 | * @inheritdoc
70 | */
71 | public function transactions()
72 | {
73 | return [
74 | self::SCENARIO_DEFAULT => self::OP_ALL,
75 | ];
76 | }
77 |
78 | /**
79 | * @return NodeQuery
80 | */
81 | public static function find()
82 | {
83 | return new NodeQuery(get_called_class());
84 | }
85 | }
--------------------------------------------------------------------------------
/tests/models/NodeAlNi.php:
--------------------------------------------------------------------------------
1 |
5 | * @license MIT (https://github.com/paulzi/yii2-auto-tree/blob/master/LICENSE)
6 | */
7 |
8 | namespace paulzi\autotree\tests\models;
9 |
10 | use paulzi\adjacencyList\AdjacencyListBehavior;
11 | use paulzi\nestedintervals\NestedIntervalsBehavior;
12 | use paulzi\autotree\AutoTreeTrait;
13 |
14 | /**
15 | * @author PaulZi
16 | *
17 | * @property integer $id
18 | * @property integer $parent_id
19 | * @property integer $sort
20 | * @property integer $tree
21 | * @property integer $lft
22 | * @property integer $rgt
23 | * @property integer $depth
24 | * @property string $path
25 | * @property string $slug
26 | *
27 | * @property NodeAlNi[] $parents
28 | * @property NodeAlNi $parent
29 | * @property NodeAlNi $root
30 | * @property NodeAlNi[] $descendants
31 | * @property NodeAlNi[] $children
32 | * @property NodeAlNi[] $leaves
33 | * @property NodeAlNi $prev
34 | * @property NodeAlNi $next
35 | *
36 | * @method static NodeAlNi|null findOne() findOne($condition)
37 | *
38 | * @mixin AdjacencyListBehavior
39 | * @mixin NestedIntervalsBehavior
40 | */
41 | class NodeAlNi extends \yii\db\ActiveRecord
42 | {
43 | use AutoTreeTrait;
44 |
45 | /**
46 | * @inheritdoc
47 | */
48 | public static function tableName()
49 | {
50 | return '{{%tree}}';
51 | }
52 | /**
53 | * @inheritdoc
54 | */
55 | public function behaviors()
56 | {
57 | return [
58 | [
59 | 'class' => AdjacencyListBehavior::className(),
60 | 'sortable' => false,
61 | ],
62 | [
63 | 'class' => NestedIntervalsBehavior::className(),
64 | 'treeAttribute' => 'tree',
65 | ],
66 | ];
67 | }
68 |
69 | /**
70 | * @inheritdoc
71 | */
72 | public function transactions()
73 | {
74 | return [
75 | self::SCENARIO_DEFAULT => self::OP_ALL,
76 | ];
77 | }
78 |
79 | /**
80 | * @return NodeQuery
81 | */
82 | public static function find()
83 | {
84 | return new NodeQuery(get_called_class());
85 | }
86 | }
--------------------------------------------------------------------------------
/tests/models/NodeAlNs.php:
--------------------------------------------------------------------------------
1 |
5 | * @license MIT (https://github.com/paulzi/yii2-auto-tree/blob/master/LICENSE)
6 | */
7 |
8 | namespace paulzi\autotree\tests\models;
9 |
10 | use paulzi\adjacencyList\AdjacencyListBehavior;
11 | use paulzi\nestedsets\NestedSetsBehavior;
12 | use paulzi\autotree\AutoTreeTrait;
13 |
14 | /**
15 | * @author PaulZi
16 | *
17 | * @property integer $id
18 | * @property integer $parent_id
19 | * @property integer $sort
20 | * @property integer $tree
21 | * @property integer $lft
22 | * @property integer $rgt
23 | * @property integer $depth
24 | * @property string $path
25 | * @property string $slug
26 | *
27 | * @property NodeAlNs[] $parents
28 | * @property NodeAlNs $parent
29 | * @property NodeAlNs $root
30 | * @property NodeAlNs[] $descendants
31 | * @property NodeAlNs[] $children
32 | * @property NodeAlNs[] $leaves
33 | * @property NodeAlNs $prev
34 | * @property NodeAlNs $next
35 | *
36 | * @method static NodeAlNs|null findOne() findOne($condition)
37 | *
38 | * @mixin AdjacencyListBehavior
39 | * @mixin NestedSetsBehavior
40 | */
41 | class NodeAlNs extends \yii\db\ActiveRecord
42 | {
43 | use AutoTreeTrait;
44 |
45 | /**
46 | * @inheritdoc
47 | */
48 | public static function tableName()
49 | {
50 | return '{{%tree}}';
51 | }
52 | /**
53 | * @inheritdoc
54 | */
55 | public function behaviors()
56 | {
57 | return [
58 | [
59 | 'class' => AdjacencyListBehavior::className(),
60 | 'sortable' => false,
61 | ],
62 | [
63 | 'class' => NestedSetsBehavior::className(),
64 | 'treeAttribute' => 'tree',
65 | ],
66 | ];
67 | }
68 |
69 | /**
70 | * @inheritdoc
71 | */
72 | public function transactions()
73 | {
74 | return [
75 | self::SCENARIO_DEFAULT => self::OP_ALL,
76 | ];
77 | }
78 |
79 | /**
80 | * @return NodeQuery
81 | */
82 | public static function find()
83 | {
84 | return new NodeQuery(get_called_class());
85 | }
86 | }
--------------------------------------------------------------------------------
/tests/models/NodeQuery.php:
--------------------------------------------------------------------------------
1 |
5 | * @license MIT (https://github.com/paulzi/yii2-auto-tree/blob/master/LICENSE)
6 | */
7 |
8 | namespace paulzi\autotree\tests\models;
9 |
10 | use paulzi\adjacencyList\AdjacencyListQueryTrait;
11 |
12 | /**
13 | * @author PaulZi
14 | */
15 | class NodeQuery extends \yii\db\ActiveQuery
16 | {
17 | use AdjacencyListQueryTrait;
18 | }
--------------------------------------------------------------------------------