diff --git a/.github/workflows/CI.yaml b/.github/workflows/CI.yaml new file mode 100644 index 0000000..a1008fb --- /dev/null +++ b/.github/workflows/CI.yaml @@ -0,0 +1,98 @@ +name: Tests + +# Run this workflow every time a new commit pushed to your repository +on: + push: + paths-ignore: + - '**/*.md' + pull_request: + paths-ignore: + - '**/*.md' + +jobs: + tests: + runs-on: ${{ matrix.operating-system }} + if: (github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository) + + strategy: + fail-fast: false + matrix: + operating-system: [ubuntu-20.04] + php-versions: ['7.4', '8.0', '8.1'] + dependencies: ['no', 'low', 'beta'] + include: + - operating-system: ubuntu-20.04 + php-versions: '8.0' + continue-on-error: true + + name: PHP ${{ matrix.php-versions }} - ${{ matrix.dependencies }} + + env: + extensions: curl json libxml dom + key: cache-v1 # can be any string, change to clear the extension cache. + + steps: + + # Checks out a copy of your repository on the ubuntu machine + - name: Checkout code + uses: actions/checkout@v2 + + - name: Setup cache environment + id: extcache + uses: shivammathur/cache-extensions@v1 + with: + php-version: ${{ matrix.php-versions }} + extensions: ${{ env.extensions }} + key: ${{ env.key }} + + - name: Cache PHP Extensions + uses: actions/cache@v2 + with: + path: ${{ steps.extcache.outputs.dir }} + key: ${{ steps.extcache.outputs.key }} + restore-keys: ${{ steps.extcache.outputs.key }} + + - name: Cache Composer Dependencies + uses: actions/cache@v1 + with: + path: ~/.composer/cache/files + key: dependencies-composer-${{ hashFiles('composer.json') }} + + - name: Setup PHP Action + uses: shivammathur/setup-php@2.8.0 + with: + php-version: ${{ matrix.php-versions }} + extensions: ${{ env.extensions }} + coverage: xdebug + tools: pecl, composer + + - name: PHP Show modules + run: php -m + + - name: Get composer cache directory + id: composer-cache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + + - name: Cache dependencies + uses: actions/cache@v2 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: ${{ runner.os }}-composer- + + - name: Install Composer dependencies + if: ${{ matrix.dependencies != 'low' }} + run: composer update --no-interaction + + - name: Install Composer dependencies + if: ${{ matrix.dependencies == 'low' }} + run: composer update -vvv --prefer-lowest --prefer-stable --no-interaction + + - name: Validate files + run: composer validate-files + + - name: Check Style + run: composer check-code-style + + # - name: Run tests + # run: composer run-tests diff --git a/.gitignore b/.gitignore index 8879189..24a2013 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ composer.phar composer.lock .DS_Store +.php-cs-fixer.cache +.phpunit.result.cache diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index d0ba93c..0000000 --- a/.travis.yml +++ /dev/null @@ -1,15 +0,0 @@ -language: php - -php: - - 5.5 - - 5.6 - - 7.1 - - 7.2 - - 7.3 - - 7.4 - -before_script: - - curl -s http://getcomposer.org/installer | php - - php composer.phar install --dev - -script: phpunit \ No newline at end of file diff --git a/composer.json b/composer.json index 551bcaa..568552b 100644 --- a/composer.json +++ b/composer.json @@ -25,9 +25,26 @@ }, "require-dev": { - "phpunit/phpunit": "7.*" - }, + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpmd/phpmd": "^2.9", + "phpunit/phpunit": "^9.3", + "sebastian/phpcpd": ">=4.1", + "friendsofphp/php-cs-fixer": ">=2.17", + "squizlabs/php_codesniffer": "^3.5" + }, + "scripts": { + "check-code-style": [ + "vendor/bin/phpcs --standard=PSR2 ./src/" + ], + "run-tests": [ + "vendor/bin/phpunit -c phpunit.xml", + "vendor/bin/phpunit --coverage-clover=coverage.xml" + ], + "validate-files": [ + "vendor/bin/parallel-lint --exclude vendor ." + ] + }, "minimum-stability": "dev", "prefer-stable": true, diff --git a/phpunit.xml b/phpunit.xml index 1e71a58..0ea8ac9 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,22 +1,13 @@ - - - - - ./tests/ - - - - - - ./src - - - \ No newline at end of file + + + + + ./src + + + + + ./tests/ + + + diff --git a/src/AncestorsRelation.php b/src/AncestorsRelation.php index b59fba2..38736bd 100644 --- a/src/AncestorsRelation.php +++ b/src/AncestorsRelation.php @@ -13,7 +13,9 @@ class AncestorsRelation extends BaseRelation */ public function addConstraints() { - if ( ! static::$constraints) return; + if (! static::$constraints) { + return; + } $this->query->whereAncestorOf($this->parent) ->applyNestedSetScope(); diff --git a/src/BaseRelation.php b/src/BaseRelation.php index 3b3b592..21fa1f6 100644 --- a/src/BaseRelation.php +++ b/src/BaseRelation.php @@ -36,7 +36,7 @@ abstract class BaseRelation extends Relation */ public function __construct(QueryBuilder $builder, Model $model) { - if ( ! NestedSet::isNode($model)) { + if (! NestedSet::isNode($model)) { throw new InvalidArgumentException('Model must be node.'); } @@ -76,8 +76,10 @@ abstract protected function relationExistenceCondition($hash, $table, $lft, $rgt * * @return mixed */ - public function getRelationExistenceQuery(EloquentBuilder $query, EloquentBuilder $parent, - $columns = [ '*' ] + public function getRelationExistenceQuery( + EloquentBuilder $query, + EloquentBuilder $parent, + $columns = [ '*' ] ) { $query = $this->getParent()->replicate()->newScopedQuery()->select($columns); @@ -93,7 +95,8 @@ public function getRelationExistenceQuery(EloquentBuilder $query, EloquentBuilde $grammar->wrapTable($hash), $grammar->wrapTable($table), $grammar->wrap($this->parent->getLftName()), - $grammar->wrap($this->parent->getRgtName())); + $grammar->wrap($this->parent->getRgtName()) + ); return $query->whereRaw($condition); } @@ -119,7 +122,8 @@ public function initRelation(array $models, $relation) * @return mixed */ public function getRelationQuery( - EloquentBuilder $query, EloquentBuilder $parent, + EloquentBuilder $query, + EloquentBuilder $parent, $columns = [ '*' ] ) { return $this->getRelationExistenceQuery($query, $parent, $columns); diff --git a/src/Collection.php b/src/Collection.php index 2dd26df..0664add 100644 --- a/src/Collection.php +++ b/src/Collection.php @@ -16,13 +16,15 @@ class Collection extends BaseCollection */ public function linkNodes() { - if ($this->isEmpty()) return $this; + if ($this->isEmpty()) { + return $this; + } $groupedNodes = $this->groupBy($this->first()->getParentIdName()); /** @var NodeTrait|Model $node */ foreach ($this->items as $node) { - if ( ! $node->getParentId()) { + if (! $node->getParentId()) { $node->setRelation('parent', null); } @@ -53,7 +55,7 @@ public function linkNodes() public function toTree($root = false) { if ($this->isEmpty()) { - return new static; + return new static(); } $this->linkNodes(); @@ -112,9 +114,11 @@ protected function getRootNodeId($root = false) */ public function toFlatTree($root = false) { - $result = new static; + $result = new static(); - if ($this->isEmpty()) return $result; + if ($this->isEmpty()) { + return $result; + } $groupedNodes = $this->groupBy($this->first()->getParentIdName()); @@ -139,5 +143,4 @@ protected function flattenTree(self $groupedNodes, $parentId) return $this; } - -} \ No newline at end of file +} diff --git a/src/DescendantsRelation.php b/src/DescendantsRelation.php index 4c6457d..fd0bbb1 100644 --- a/src/DescendantsRelation.php +++ b/src/DescendantsRelation.php @@ -7,7 +7,6 @@ class DescendantsRelation extends BaseRelation { - /** * Set the base constraints on the relation query. * @@ -15,7 +14,9 @@ class DescendantsRelation extends BaseRelation */ public function addConstraints() { - if ( ! static::$constraints) return; + if (! static::$constraints) { + return; + } $this->query->whereDescendantOf($this->parent) ->applyNestedSetScope(); @@ -53,4 +54,4 @@ protected function relationExistenceCondition($hash, $table, $lft, $rgt) { return "{$hash}.{$lft} between {$table}.{$lft} + 1 and {$table}.{$rgt}"; } -} \ No newline at end of file +} diff --git a/src/NestedSet.php b/src/NestedSet.php index 7045471..df8bc1c 100644 --- a/src/NestedSet.php +++ b/src/NestedSet.php @@ -9,27 +9,27 @@ class NestedSet /** * The name of default lft column. */ - const LFT = '_lft'; + public const LFT = '_lft'; /** * The name of default rgt column. */ - const RGT = '_rgt'; + public const RGT = '_rgt'; /** * The name of default parent id column. */ - const PARENT_ID = 'parent_id'; + public const PARENT_ID = 'parent_id'; /** * Insert direction. */ - const BEFORE = 1; + public const BEFORE = 1; /** * Insert direction. */ - const AFTER = 2; + public const AFTER = 2; /** * Add default nested set columns to the table. Also create an index. @@ -79,5 +79,4 @@ public static function isNode($node) { return $node instanceof Node; } - -} \ No newline at end of file +} diff --git a/src/NestedSetServiceProvider.php b/src/NestedSetServiceProvider.php index b4516f7..16466b4 100644 --- a/src/NestedSetServiceProvider.php +++ b/src/NestedSetServiceProvider.php @@ -17,4 +17,4 @@ public function register() NestedSet::dropColumns($this); }); } -} \ No newline at end of file +} diff --git a/src/Node.php b/src/Node.php index dfcb12f..9539447 100644 --- a/src/Node.php +++ b/src/Node.php @@ -20,344 +20,344 @@ */ interface Node { - /** - * Relation to the parent. - * - * @return BelongsTo - */ - public function parent(); - - /** - * Relation to children. - * - * @return HasMany - */ - public function children(); - - /** - * Get query for descendants of the node. - * - * @return DescendantsRelation - */ - public function descendants(); - - /** - * Get query for siblings of the node. - * - * @return QueryBuilder - */ - public function siblings(); - - /** - * Get the node siblings and the node itself. - * - * @return QueryBuilder - */ - public function siblingsAndSelf(); - - /** - * Get query for the node siblings and the node itself. - * - * @param array $columns - * - * @return EloquentCollection - */ - public function getSiblingsAndSelf(array $columns = ['*']); - - /** - * Get query for siblings after the node. - * - * @return QueryBuilder - */ - public function nextSiblings(); - - /** - * Get query for siblings before the node. - * - * @return QueryBuilder - */ - public function prevSiblings(); - - /** - * Get query for nodes after current node. - * - * @return QueryBuilder - */ - public function nextNodes(); - - /** - * Get query for nodes before current node in reversed order. - * - * @return QueryBuilder - */ - public function prevNodes(); - - /** - * Get query ancestors of the node. - * - * @return AncestorsRelation - */ - public function ancestors(); - - /** - * Make this node a root node. - * - * @return $this - */ - public function makeRoot(); - - /** - * Save node as root. - * - * @return bool - */ - public function saveAsRoot(); - - /** - * @param $lft - * @param $rgt - * @param $parentId - * - * @return $this - */ - public function rawNode($lft, $rgt, $parentId); - - /** - * Move node up given amount of positions. - * - * @param int $amount - * - * @return bool - */ - public function up($amount = 1); - - /** - * Move node down given amount of positions. - * - * @param int $amount - * - * @return bool - */ - public function down($amount = 1); - - /** - * @since 2.0 - */ - public function newEloquentBuilder($query); - - /** - * Get a new base query that includes deleted nodes. - * - * @since 1.1 - * - * @return QueryBuilder - */ - public function newNestedSetQuery($table = null); - - /** - * @param ?string $table - * - * @return QueryBuilder - */ - public function newScopedQuery($table = null); - - /** - * @param mixed $query - * @param ?string $table - * - * @return mixed - */ - public function applyNestedSetScope($query, $table = null); - - /** - * @param array $attributes - * - * @return self - */ - public static function scoped(array $attributes); - - public function newCollection(array $models = []); - - /** - * Get node height (rgt - lft + 1). - * - * @return int - */ - public function getNodeHeight(); - - /** - * Get number of descendant nodes. - * - * @return int - */ - public function getDescendantCount(); - - /** - * Set the value of model's parent id key. - * - * Behind the scenes node is appended to found parent node. - * - * @param int $value - * - * @throws \Exception If parent node doesn't exists - */ - public function setParentIdAttribute($value); - - /** - * Get whether node is root. - * - * @return bool - */ - public function isRoot(); - - /** - * @return bool - */ - public function isLeaf(); - - /** - * Get the lft key name. - * - * @return string - */ - public function getLftName(); - - /** - * Get the rgt key name. - * - * @return string - */ - public function getRgtName(); - - /** - * Get the parent id key name. - * - * @return string - */ - public function getParentIdName(); - - /** - * Get the value of the model's lft key. - * - * @return int - */ - public function getLft(); - - /** - * Get the value of the model's rgt key. - * - * @return int - */ - public function getRgt(); - - /** - * Get the value of the model's parent id key. - * - * @return int - */ - public function getParentId(); - - /** - * Returns node that is next to current node without constraining to siblings. - * - * This can be either a next sibling or a next sibling of the parent node. - * - * @param array $columns - * - * @return self - */ - public function getNextNode(array $columns = ['*']); - - /** - * Returns node that is before current node without constraining to siblings. - * - * This can be either a prev sibling or parent node. - * - * @param array $columns - * - * @return self - */ - public function getPrevNode(array $columns = ['*']); - - /** - * @param array $columns - * - * @return Collection - */ - public function getAncestors(array $columns = ['*']); - - /** - * @param array $columns - * - * @return Collection|self[] - */ - public function getDescendants(array $columns = ['*']); - - /** - * @param array $columns - * - * @return Collection|self[] - */ - public function getSiblings(array $columns = ['*']); - - /** - * @param array $columns - * - * @return Collection - */ - public function getNextSiblings(array $columns = ['*']); - - /** - * @param array $columns - * - * @return Collection - */ - public function getPrevSiblings(array $columns = ['*']); - - /** - * @param array $columns - * - * @return Node - */ - public function getNextSibling(array $columns = ['*']); - - /** - * @param array $columns - * - * @return Node - */ - public function getPrevSibling(array $columns = ['*']); - - /** - * @return array - */ - public function getBounds(); - - /** - * @param $value - * - * @return $this - */ - public function setLft($value); - - /** - * @param $value - * - * @return $this - */ - public function setRgt($value); - - /** - * @param $value - * - * @return $this - */ - public function setParentId($value); - - /** - * @param array|null $except - * - * @return $this - */ - public function replicate(array $except = null); + /** + * Relation to the parent. + * + * @return BelongsTo + */ + public function parent(); + + /** + * Relation to children. + * + * @return HasMany + */ + public function children(); + + /** + * Get query for descendants of the node. + * + * @return DescendantsRelation + */ + public function descendants(); + + /** + * Get query for siblings of the node. + * + * @return QueryBuilder + */ + public function siblings(); + + /** + * Get the node siblings and the node itself. + * + * @return QueryBuilder + */ + public function siblingsAndSelf(); + + /** + * Get query for the node siblings and the node itself. + * + * @param array $columns + * + * @return EloquentCollection + */ + public function getSiblingsAndSelf(array $columns = ['*']); + + /** + * Get query for siblings after the node. + * + * @return QueryBuilder + */ + public function nextSiblings(); + + /** + * Get query for siblings before the node. + * + * @return QueryBuilder + */ + public function prevSiblings(); + + /** + * Get query for nodes after current node. + * + * @return QueryBuilder + */ + public function nextNodes(); + + /** + * Get query for nodes before current node in reversed order. + * + * @return QueryBuilder + */ + public function prevNodes(); + + /** + * Get query ancestors of the node. + * + * @return AncestorsRelation + */ + public function ancestors(); + + /** + * Make this node a root node. + * + * @return $this + */ + public function makeRoot(); + + /** + * Save node as root. + * + * @return bool + */ + public function saveAsRoot(); + + /** + * @param $lft + * @param $rgt + * @param $parentId + * + * @return $this + */ + public function rawNode($lft, $rgt, $parentId); + + /** + * Move node up given amount of positions. + * + * @param int $amount + * + * @return bool + */ + public function up($amount = 1); + + /** + * Move node down given amount of positions. + * + * @param int $amount + * + * @return bool + */ + public function down($amount = 1); + + /** + * @since 2.0 + */ + public function newEloquentBuilder($query); + + /** + * Get a new base query that includes deleted nodes. + * + * @since 1.1 + * + * @return QueryBuilder + */ + public function newNestedSetQuery($table = null); + + /** + * @param ?string $table + * + * @return QueryBuilder + */ + public function newScopedQuery($table = null); + + /** + * @param mixed $query + * @param ?string $table + * + * @return mixed + */ + public function applyNestedSetScope($query, $table = null); + + /** + * @param array $attributes + * + * @return self + */ + public static function scoped(array $attributes); + + public function newCollection(array $models = []); + + /** + * Get node height (rgt - lft + 1). + * + * @return int + */ + public function getNodeHeight(); + + /** + * Get number of descendant nodes. + * + * @return int + */ + public function getDescendantCount(); + + /** + * Set the value of model's parent id key. + * + * Behind the scenes node is appended to found parent node. + * + * @param int $value + * + * @throws \Exception If parent node doesn't exists + */ + public function setParentIdAttribute($value); + + /** + * Get whether node is root. + * + * @return bool + */ + public function isRoot(); + + /** + * @return bool + */ + public function isLeaf(); + + /** + * Get the lft key name. + * + * @return string + */ + public function getLftName(); + + /** + * Get the rgt key name. + * + * @return string + */ + public function getRgtName(); + + /** + * Get the parent id key name. + * + * @return string + */ + public function getParentIdName(); + + /** + * Get the value of the model's lft key. + * + * @return int + */ + public function getLft(); + + /** + * Get the value of the model's rgt key. + * + * @return int + */ + public function getRgt(); + + /** + * Get the value of the model's parent id key. + * + * @return int + */ + public function getParentId(); + + /** + * Returns node that is next to current node without constraining to siblings. + * + * This can be either a next sibling or a next sibling of the parent node. + * + * @param array $columns + * + * @return self + */ + public function getNextNode(array $columns = ['*']); + + /** + * Returns node that is before current node without constraining to siblings. + * + * This can be either a prev sibling or parent node. + * + * @param array $columns + * + * @return self + */ + public function getPrevNode(array $columns = ['*']); + + /** + * @param array $columns + * + * @return Collection + */ + public function getAncestors(array $columns = ['*']); + + /** + * @param array $columns + * + * @return Collection|self[] + */ + public function getDescendants(array $columns = ['*']); + + /** + * @param array $columns + * + * @return Collection|self[] + */ + public function getSiblings(array $columns = ['*']); + + /** + * @param array $columns + * + * @return Collection + */ + public function getNextSiblings(array $columns = ['*']); + + /** + * @param array $columns + * + * @return Collection + */ + public function getPrevSiblings(array $columns = ['*']); + + /** + * @param array $columns + * + * @return Node + */ + public function getNextSibling(array $columns = ['*']); + + /** + * @param array $columns + * + * @return Node + */ + public function getPrevSibling(array $columns = ['*']); + + /** + * @return array + */ + public function getBounds(); + + /** + * @param $value + * + * @return $this + */ + public function setLft($value); + + /** + * @param $value + * + * @return $this + */ + public function setRgt($value); + + /** + * @param $value + * + * @return $this + */ + public function setParentId($value); + + /** + * @param array|null $except + * + * @return $this + */ + public function replicate(array $except = null); } diff --git a/src/NodeTrait.php b/src/NodeTrait.php index 0b985ab..e7f0366 100644 --- a/src/NodeTrait.php +++ b/src/NodeTrait.php @@ -88,11 +88,13 @@ protected function callPendingAction() { $this->moved = false; - if ( ! $this->pending && ! $this->exists) { + if (! $this->pending && ! $this->exists) { $this->makeRoot(); } - if ( ! $this->pending) return; + if (! $this->pending) { + return; + } $method = 'action'.ucfirst(array_shift($this->pending)); $parameters = $this->pending; @@ -110,7 +112,7 @@ public static function usesSoftDelete() static $softDelete; if (is_null($softDelete)) { - $instance = new static; + $instance = new static(); return $softDelete = method_exists($instance, 'bootSoftDeletes'); } @@ -132,7 +134,7 @@ protected function actionRaw() protected function actionRoot() { // Simplest case that do not affect other nodes. - if ( ! $this->exists) { + if (! $this->exists) { $cut = $this->getLowerBound() + 1; $this->setLft($cut); @@ -168,7 +170,7 @@ protected function actionAppendOrPrepend(self $parent, $prepend = false) $cut = $prepend ? $parent->getLft() + 1 : $parent->getRgt(); - if ( ! $this->insertAt($cut)) { + if (! $this->insertAt($cut)) { return false; } @@ -212,7 +214,9 @@ protected function actionBeforeOrAfter(self $node, $after = false) */ public function refreshNode() { - if ( ! $this->exists || static::$actionsPerformed === 0) return; + if (! $this->exists || static::$actionsPerformed === 0) { + return; + } $attributes = $this->newNestedSetQuery()->getNodeData($this->getKey()); @@ -468,7 +472,7 @@ public function beforeOrAfterNode(self $node, $after = false) ->assertNotDescendant($node) ->assertSameScope($node); - if ( ! $this->isSiblingOf($node)) { + if (! $this->isSiblingOf($node)) { $this->setParent($node->getRelationValue('parent')); } @@ -498,7 +502,9 @@ public function insertAfterNode(self $node) */ public function insertBeforeNode(self $node) { - if ( ! $this->beforeNode($node)->save()) return false; + if (! $this->beforeNode($node)->save()) { + return false; + } // We'll update the target node since it will be moved $node->refreshNode(); @@ -534,7 +540,9 @@ public function up($amount = 1) ->skip($amount - 1) ->first(); - if ( ! $sibling) return false; + if (! $sibling) { + return false; + } return $this->insertBeforeNode($sibling); } @@ -553,7 +561,9 @@ public function down($amount = 1) ->skip($amount - 1) ->first(); - if ( ! $sibling) return false; + if (! $sibling) { + return false; + } return $this->insertAfterNode($sibling); } @@ -590,7 +600,9 @@ protected function moveNode($position) $updated = $this->newNestedSetQuery() ->moveNode($this->getKey(), $position) > 0; - if ($updated) $this->refreshNode(); + if ($updated) { + $this->refreshNode(); + } return $updated; } @@ -698,17 +710,20 @@ public function newScopedQuery($table = null) */ public function applyNestedSetScope($query, $table = null) { - if ( ! $scoped = $this->getScopeAttributes()) { + if (! $scoped = $this->getScopeAttributes()) { return $query; } - if ( ! $table) { + if (! $table) { $table = $this->getTable(); } foreach ($scoped as $attribute) { - $query->where($table.'.'.$attribute, '=', - $this->getAttributeValue($attribute)); + $query->where( + $table.'.'.$attribute, + '=', + $this->getAttributeValue($attribute) + ); } return $query; @@ -729,7 +744,7 @@ protected function getScopeAttributes() */ public static function scoped(array $attributes) { - $instance = new static; + $instance = new static(); $instance->setRawAttributes($attributes); @@ -764,7 +779,7 @@ public static function create(array $attributes = [], self $parent = null) $instance->save(); // Now create children - $relation = new EloquentCollection; + $relation = new EloquentCollection(); foreach ((array)$children as $child) { $relation->add($child = static::create($child, $instance)); @@ -784,7 +799,9 @@ public static function create(array $attributes = [], self $parent = null) */ public function getNodeHeight() { - if ( ! $this->exists) return 2; + if (! $this->exists) { + return 2; + } return $this->getRgt() - $this->getLft() + 1; } @@ -810,7 +827,9 @@ public function getDescendantCount() */ public function setParentIdAttribute($value) { - if ($this->getParentId() == $value) return; + if ($this->getParentId() == $value) { + return; + } if ($value) { $this->appendToNode($this->newScopedQuery()->findOrFail($value)); @@ -1178,7 +1197,7 @@ protected function assertNotDescendant(self $node) */ protected function assertNodeExists(self $node) { - if ( ! $node->getLft() || ! $node->getRgt()) { + if (! $node->getLft() || ! $node->getRgt()) { throw new LogicException('Node must exists.'); } @@ -1190,7 +1209,7 @@ protected function assertNodeExists(self $node) */ protected function assertSameScope(self $node) { - if ( ! $scoped = $this->getScopeAttributes()) { + if (! $scoped = $this->getScopeAttributes()) { return; } diff --git a/src/QueryBuilder.php b/src/QueryBuilder.php index 61aba6a..9b794e1 100644 --- a/src/QueryBuilder.php +++ b/src/QueryBuilder.php @@ -38,8 +38,8 @@ public function getNodeData($id, $required = false) $data = $query->first([ $this->model->getLftName(), $this->model->getRgtName() ]); - if ( ! $data && $required) { - throw new ModelNotFoundException; + if (! $data && $required) { + throw new ModelNotFoundException(); } return (array)$data; @@ -114,7 +114,7 @@ public function whereAncestorOf($id, $andSelf = false, $boolean = 'and') $inner->whereRaw("{$value} between {$wrappedTable}.{$lft} and {$wrappedTable}.{$rgt}"); - if ( ! $andSelf) { + if (! $andSelf) { $inner->where($keyName, '<>', $id); } }, $boolean); @@ -183,7 +183,12 @@ public function ancestorsAndSelf($id, array $columns = [ '*' ]) */ public function whereNodeBetween($values, $boolean = 'and', $not = false) { - $this->query->whereBetween($this->model->getTable() . '.' . $this->model->getLftName(), $values, $boolean, $not); + $this->query->whereBetween( + $this->model->getTable() . '.' . $this->model->getLftName(), + $values, + $boolean, + $not + ); return $this; } @@ -214,8 +219,11 @@ public function orWhereNodeBetween($values) * * @return $this */ - public function whereDescendantOf($id, $boolean = 'and', $not = false, - $andSelf = false + public function whereDescendantOf( + $id, + $boolean = 'and', + $not = false, + $andSelf = false ) { if (NestedSet::isNode($id)) { $data = $id->getBounds(); @@ -225,7 +233,7 @@ public function whereDescendantOf($id, $boolean = 'and', $not = false, } // Don't include the node - if ( ! $andSelf) { + if (! $andSelf) { ++$data[0]; } @@ -289,9 +297,7 @@ public function descendantsOf($id, array $columns = [ '*' ], $andSelf = false) { try { return $this->whereDescendantOf($id, 'and', false, $andSelf)->get($columns); - } - - catch (ModelNotFoundException $e) { + } catch (ModelNotFoundException $e) { return $this->model->newCollection(); } } @@ -333,7 +339,7 @@ protected function whereIsBeforeOrAfter($id, $operator, $boolean) $value = '('.$valueQuery->toSql().')'; } - list($lft,) = $this->wrappedColumns(); + list($lft, ) = $this->wrappedColumns(); $this->query->whereRaw("{$lft} {$operator} {$value}", [ ], $boolean); @@ -399,7 +405,9 @@ public function leaves(array $columns = [ '*']) */ public function withDepth($as = 'depth') { - if ($this->query->columns === null) $this->query->columns = [ '*' ]; + if ($this->query->columns === null) { + $this->query->columns = [ '*' ]; + } $table = $this->wrappedTable(); @@ -640,7 +648,9 @@ protected function columnPatch($col, array $params) extract($params); /** @var int $height */ - if ($height > 0) $height = '+'.$height; + if ($height > 0) { + $height = '+'.$height; + } if (isset($cut)) { return new Expression("case when {$col} >= {$cut} then {$col}{$height} else {$col} end"); @@ -651,9 +661,12 @@ protected function columnPatch($col, array $params) /** @var int $rgt */ /** @var int $from */ /** @var int $to */ - if ($distance > 0) $distance = '+'.$distance; + if ($distance > 0) { + $distance = '+'.$distance; + } - return new Expression("case ". + return new Expression( + "case ". "when {$col} between {$lft} and {$rgt} then {$col}{$distance} ". // Move the node "when {$col} between {$from} and {$to} then {$col}{$height} ". // Move other nodes "else {$col} end" @@ -896,7 +909,7 @@ protected function fixNodes(array &$dictionary, $parent = null) $cut = self::reorderNodes($dictionary, $updated, $parentId, $cut); // Save nodes that have invalid parent as roots - while ( ! empty($dictionary)) { + while (! empty($dictionary)) { $dictionary[null] = reset($dictionary); unset($dictionary[key($dictionary)]); @@ -927,9 +940,12 @@ protected function fixNodes(array &$dictionary, $parent = null) * @internal param int $fixed */ protected static function reorderNodes( - array &$dictionary, array &$updated, $parentId = null, $cut = 1 + array &$dictionary, + array &$updated, + $parentId = null, + $cut = 1 ) { - if ( ! isset($dictionary[$parentId])) { + if (! isset($dictionary[$parentId])) { return $cut; } @@ -982,7 +998,7 @@ public function rebuildTree(array $data, $delete = false, $root = null) $this->buildRebuildDictionary($dictionary, $data, $existing, $parentId); /** @var Model|NodeTrait $model */ - if ( ! empty($existing)) { + if (! empty($existing)) { if ($delete && ! $this->model->usesSoftDelete()) { $this->model ->newScopedQuery() @@ -1024,24 +1040,25 @@ public function rebuildSubtree($root, array $data, $delete = false) * @param array $existing * @param mixed $parentId */ - protected function buildRebuildDictionary(array &$dictionary, - array $data, - array &$existing, - $parentId = null + protected function buildRebuildDictionary( + array &$dictionary, + array $data, + array &$existing, + $parentId = null ) { $keyName = $this->model->getKeyName(); foreach ($data as $itemData) { /** @var NodeTrait|Model $model */ - if ( ! isset($itemData[$keyName])) { + if (! isset($itemData[$keyName])) { $model = $this->model->newInstance($this->model->getAttributes()); // Set some values that will be fixed later $model->rawNode(0, 0, $parentId); } else { - if ( ! isset($existing[$key = $itemData[$keyName]])) { - throw new ModelNotFoundException; + if (! isset($existing[$key = $itemData[$keyName]])) { + throw new ModelNotFoundException(); } $model = $existing[$key]; @@ -1056,12 +1073,16 @@ protected function buildRebuildDictionary(array &$dictionary, $dictionary[$parentId][] = $model; - if ( ! isset($itemData['children'])) continue; + if (! isset($itemData['children'])) { + continue; + } - $this->buildRebuildDictionary($dictionary, - $itemData['children'], - $existing, - $model->getKey()); + $this->buildRebuildDictionary( + $dictionary, + $itemData['children'], + $existing, + $model->getKey() + ); } } diff --git a/tests/NodeTest.php b/tests/NodeTest.php index 7c2fbae..d565ca2 100644 --- a/tests/NodeTest.php +++ b/tests/NodeTest.php @@ -5,7 +5,7 @@ class NodeTest extends PHPUnit\Framework\TestCase { - public static function setUpBeforeClass() + public static function setUpBeforeClass() : void { $schema = Capsule::schema(); @@ -23,7 +23,7 @@ public static function setUpBeforeClass() Capsule::enableQueryLog(); } - public function setUp() + public function setUp() : void { $data = include __DIR__.'/data/categories.php'; @@ -36,7 +36,7 @@ public function setUp() date_default_timezone_set('America/Denver'); } - public function tearDown() + public function tearDown() : void { Capsule::table('categories')->truncate(); } @@ -84,7 +84,9 @@ public function assertTreeNotBroken($table = 'categories') public function dumpTree($items = null) { - if ( ! $items) $items = Category::withTrashed()->defaultOrder()->get(); + if (! $items) { + $items = Category::withTrashed()->defaultOrder()->get(); + } foreach ($items as $item) { echo PHP_EOL.($item->trashed() ? '-' : '+').' '.$item->name." ".$item->getKey().' '.$item->getLft()." ".$item->getRgt().' '.$item->getParentId(); @@ -615,14 +617,15 @@ public function testCreatesViaRelationship() public function testCreatesTree() { $node = Category::create( - [ + [ 'name' => 'test', 'children' => [ [ 'name' => 'test2' ], [ 'name' => 'test3' ], ], - ]); + ] + ); $this->assertTreeNotBroken(); @@ -669,8 +672,7 @@ public function testMultipleDeletionsDoNotBrakeTree() { $category = $this->findCategory('mobile'); - foreach ($category->children()->take(2)->get() as $child) - { + foreach ($category->children()->take(2)->get() as $child) { $child->forceDelete(); } @@ -925,7 +927,9 @@ public function testEagerLoadAncestors() foreach ($categories as $category) { $output["{$category->name} ({$category->id})}"] = $category->ancestors->count() - ? implode(' > ', $category->ancestors->map(function ($cat) { return "{$cat->name} ({$cat->id})"; })->toArray()) + ? implode(' > ', $category->ancestors->map(function ($cat) { + return "{$cat->name} ({$cat->id})"; + })->toArray()) : ''; } @@ -957,7 +961,9 @@ public function testLazyLoadAncestors() foreach ($categories as $category) { $output["{$category->name} ({$category->id})}"] = $category->ancestors->count() - ? implode(' > ', $category->ancestors->map(function ($cat) { return "{$cat->name} ({$cat->id})"; })->toArray()) + ? implode(' > ', $category->ancestors->map(function ($cat) { + return "{$cat->name} ({$cat->id})"; + })->toArray()) : ''; } @@ -998,10 +1004,9 @@ public function testReplication() $this->assertEquals(1, $category->getParentId()); } - } function all($items) { return is_array($items) ? $items : $items->all(); -} \ No newline at end of file +} diff --git a/tests/ScopedNodeTest.php b/tests/ScopedNodeTest.php index f1c6921..7bcfdd2 100644 --- a/tests/ScopedNodeTest.php +++ b/tests/ScopedNodeTest.php @@ -5,7 +5,7 @@ class ScopedNodeTest extends PHPUnit\Framework\TestCase { - public static function setUpBeforeClass() + public static function setUpBeforeClass(): void { $schema = Capsule::schema(); @@ -23,7 +23,7 @@ public static function setUpBeforeClass() Capsule::enableQueryLog(); } - public function setUp() + public function setUp(): void { $data = include __DIR__.'/data/menu_items.php'; @@ -36,7 +36,7 @@ public function setUp() date_default_timezone_set('America/Denver'); } - public function tearDown() + public function tearDown(): void { Capsule::table('menu_items')->truncate(); } @@ -222,4 +222,4 @@ public function testInsertingBeforeAnotherScopeFails() $a->insertAfterNode($b); } -} \ No newline at end of file +}