HEX
Server: Microsoft-IIS/8.5
System: Windows NT YDAWBH120 6.3 build 9600 (Windows Server 2012 R2 Standard Edition) AMD64
User: tentjecom_web (0)
PHP: 7.4.14
Disabled: NONE
Upload Files
File: D:/HostingSpaces/SBogers95/rentman.io/app/Komma/Kms/Core/NestedSets/Nodes/TreeModelLogicTrait.php
<?php

namespace App\Komma\Kms\Core\NestedSets\Nodes;

/**
 * Part of the Nested Sets package.
 *
 * NOTICE OF LICENSE
 *
 * Licensed under the Cartalyst PSL License.
 *
 * This source file is subject to the Cartalyst PSL License that is
 * bundled with this package in the license.txt file.
 *
 * @version    2.0.2
 * @author     Cartalyst LLC
 * @license    Cartalyst PSL
 * @copyright  (c) 2011-2014, Cartalyst LLC
 * @link       http://cartalyst.com
 */

use App\Komma\Kms\Core\NestedSets\Presenter;
use App\Komma\Kms\Core\NestedSets\Workers\WorkerInterface;
use Closure;

trait TreeModelLogicTrait
{
    /**
     * Array of children associated with the model.
     *
     * @var array
     */
    protected $children = [];

    /**
     * Array of reserved attributes used by
     * the node. These attributes cannot be
     * set like normal attributes, they are
     * reserved for the node and nested set
     * workers to use.
     *
     * @var array
     */
    protected $reservedAttributes = [

        // The left column limit. "left" is a
        // reserved word in SQL databases so
        // we default to "lft" for compatiblity.
        'left'  => 'lft',

        // The right column limit. "right" is a
        // reserved word in SQL databases so
        // we default to "rgt" for compatiblity.
        'right' => 'rgt',

        // The tree that the node is on. This
        // package supports multiple trees within
        // the one database.
        'tree'  => 'tree',
    ];

    /**
     * The attribute used to show the depth
     * of a child when in a tree. This attribute
     * cannot be saved to the databse, it's for
     * processing and runtime usage only.
     *
     * @var string
     */
    protected $depthAttribute = 'depth';

    /**
     * The worker class which the model uses.
     *
     * @var string
     */
    protected $worker = 'App\Komma\Kms\Core\NestedSets\Workers\IlluminateWorker';

    /**
     * The presenter instance.
     *
     * @var Presenter
     */
    protected static $presenter;

    /**
     * Returns the loaded children for the node.
     *
     * @return array
     */
    public function getChildren()
    {
        return $this->children;
    }

    /**
     * Sets the children for the model.
     *
     * @param array $children
     * @return void
     */
    public function setChildren(array $children)
    {
        $this->children = $children;
    }

    /**
     * Clears the children for the model.
     *
     * @return void
     */
    public function clearChildren()
    {
        $this->children = [];
    }

    /**
     * Sets the child in the children array at
     * the given index.
     *
     * @param TreeModelInterface $child
     * @param int $index
     * @return void
     */
    public function setChildAtIndex(TreeModelInterface $child, $index)
    {
        $this->children[$index] = $child;
    }

    /**
     * Returns the child at the given index. If
     * the index does not exist, we return "null"
     *
     * @param int $index
     * @return TreeModelInterface $child
     */
    public function getChildAtIndex($index)
    {
        return isset($this->children[$index]) ? $this->children[$index] : null;
    }

    /**
     * Get the table associated with the node.
     *
     * @return string
     */
    public function getTable()
    {
        return parent::getTable();
    }

    /**
     * Get the primary key for the node.
     *
     * @return string
     */
    public function getKeyName()
    {
        return parent::getKeyName();
    }

    /**
     * Get the value indicating whether the IDs are incrementing.
     *
     * @return bool
     */
    public function getIncrementing()
    {
        return parent::getIncrementing();
    }

    /**
     * Get all of the current attributes on the node.
     *
     * @return array
     */
    public function getAllAttributes()
    {
        return $this->getAttributes();
    }

    /**
     * Set all of the current attributes on the node.
     *
     * @param array $attributes
     * @return void
     */
    public function setAllAttributes(array $attributes)
    {
        if ($this->incrementing and array_key_exists($this->primaryKey, $attributes) and $attributes[$this->primaryKey] != null) {
            $this->exists = true;
        }

        static::$unguarded = true;
        $this->fill($attributes);
        static::$unguarded = false;
    }

    /**
     * Get an attribute from the model.
     *
     * @param string $key
     * @return mixed
     */
    public function getAttribute($key)
    {
        return parent::getAttribute($key);
    }

    /**
     * Set a given attribute on the model.
     *
     * @param string $key
     * @param mixed $value
     * @return void
     */
    public function setAttribute($key, $value)
    {
        if ($this->incrementing and $key == $this->primaryKey and $value != null) {
            $this->exists = true;
        }

        parent::setAttribute($key, $value);
    }

    /**
     * Get the reserved attributes.
     *
     * @return array
     */
    public function getReservedAttributeNames()
    {
        return $this->reservedAttributes;
    }

    /**
     * Get the name of a reserved attribute.
     *
     * @param string $key
     * @return string
     */
    public function getReservedAttributeName($key)
    {
        return $this->reservedAttributes[$key];
    }

    /**
     * Return the "depth" attribute.
     *
     * @return string
     */
    public function getDepthAttributeName()
    {
        return $this->depthAttribute;
    }

    /**
     * Finds all nodes in a flat array.
     *
     * @return array
     */
    public function findAll()
    {
        return static::all()->all();
    }

    /**
     * Creates a new instance of this node.
     *
     * @return TreeModelInterface
     */
    public function createNode()
    {
        return $this->newInstance();
    }

    /**
     * Callback after the node is created in the
     * database, not necessarily through save().
     *
     * @return void
     */
    public function afterCreate()
    {
        if ($this->timestamps) {
            $this->exists = true;
            $this->setCreatedAt($time = $this->freshTimestamp());
            $this->touch();
        }
    }

    /**
     * Callback after the node is updated in the
     * database, not necessarily through save().
     *
     * @return void
     */
    public function afterUpdate()
    {
        if ($this->timestamps) {
            $this->touch();
        }
    }

    /**
     * Delete the model from the database and orphan
     * it's children.
     *
     * @return void
     */
    public function delete()
    {
        if ($this->exists) {
            $this->createWorker()->deleteNode($this);
        }
    }

    /**
     * Delete the model from the database and also
     * all of it's children.
     *
     * @return void
     */
    public function deleteWithChildren()
    {
        if ($this->exists) {
            $this->createWorker()->deleteNodeWithChildren($this);
        }
    }

    /**
     * Refreshes the node's reserved attributes from the database.
     *
     * @return void
     */
    public function refresh()
    {
        $this->createWorker()->hydrateNode($this);
    }

    /**
     * Returns if the model is a leaf node or not; whether
     * it has children.
     *
     * @return bool
     */
    public function isLeaf()
    {
        return $this->createWorker()->isLeaf($this);
    }

    /**
     * Returns the path of the node.
     *
     * @return array
     */
    public function getPath()
    {
        return $this->createWorker()->path($this);
    }

    /**
     * Returns the depth of the node.
     *
     * @return int
     */
    public function getDepth()
    {
        return $this->createWorker()->depth($this);
    }

    /**
     * Returns the parent for the node.
     *
     * @return TreeModel
     */
    public function getParent()
    {
        return $this->createWorker()->parentNode($this);
    }

    /**
     * Returns the cound of children for the model.
     *
     * @param int $depth
     * @return int
     */
    public function getChildrenCount($depth = 0)
    {
        return $this->createWorker()->childrenCount($this, $depth);
    }

    /**
     * Actually finds the children for the node.
     *
     * @param int $depth
     * @return array
     */
    public function findChildren($depth = 0)
    {
        return $this->children = $this->loadTree($depth);
    }

    /**
     * Allows you to pass through a callback when finding children,
     * to manipulate the query. Does not cache the children.
     *
     * @param Closure $callback
     * @param int $depth
     * @return array
     */
    public function filterChildren(Closure $callback, $depth = 0)
    {
        return $this->loadTree($depth, $callback);
    }

    /**
    /*
     * Makes the model a root node.
     *
     * @return void
     */
    public function makeRoot()
    {
        // @todo Allow existing items to become new root items
        if ($this->exists) {
            throw new \RuntimeException("Currently cannot make existing node {$this->getKey()} a root item.");
        }

        $this->createWorker()->insertNodeAsRoot($this);
    }

    /**
     * Makes the model the first child of the given parent.
     *
     * @param TreeModelInterface $parent
     * @return void
     */
    public function makeFirstChildOf(TreeModelInterface $parent)
    {
        $method = $this->exists ? 'moveNodeAsFirstChild' : 'insertNodeAsFirstChild';
        $this->createWorker()->$method($this, $parent);
    }

    /**
     * Makes the model the last child of the given parent.
     *
     * @param TreeModelInterface $parent
     * @return void
     */
    public function makeLastChildOf(TreeModelInterface $parent)
    {
        $method = $this->exists ? 'moveNodeAsLastChild' : 'insertNodeAsLastChild';
        $this->createWorker()->$method($this, $parent);
    }

    /**
     * Makes the model the previous sibling of the given sibling.
     *
     * @param TreeModelInterface $sibling
     * @return void
     */
    public function makePreviousSiblingOf(TreeModelInterface $sibling)
    {
        $method = $this->exists ? 'moveNodeAsPreviousSibling' : 'insertNodeAsPreviousSibling';
        $this->createWorker()->$method($this, $sibling);
    }

    /**
     * Makes the model the next sibling of the given sibling.
     *
     * @param TreeModelInterface $sibling
     * @return void
     */
    public function makeNextSiblingOf(TreeModelInterface $sibling)
    {
        $method = $this->exists ? 'moveNodeAsNextSibling' : 'insertNodeAsNextSibling';
        $this->createWorker()->$method($this, $sibling);
    }

    /**
     * Maps a tree of either nodes, arrays of StdClass objects to
     * the hierarchy array. Children nodes present in the database
     * but not present in this hierarchy will removed.
     *
     * @param mixed $nodes
     * @return void
     */
    public function mapTree($nodes)
    {
        $this->createWorker()->mapTree($this, $nodes);
    }

    /**
     * Maps a tree of either nodes, arrays of StdClass objects to
     * the hierarchy array. Children nodes present in the database
     * but not present in this hierarchy will be kept, they
     * become the first items in the tree.
     *
     * @param mixed $nodes
     * @return void
     */
    public function mapTreeAndKeep($nodes)
    {
        $this->createWorker()->mapTreeAndKeep($this, $nodes);
    }

    /**
     * Presents the node in the given format. If the attribute
     * provided is a closure, we will call it, providing every
     * single node recursively. You must return a string from
     * your closure which will be used as the output for that
     * node when presenting.
     *
     * @param string $format
     * @param string|Closure $attribute
     * @param int $depth
     * @return mixed
     */
    public function presentAs($format, $attribute, $depth = 0)
    {
        return static::$presenter->presentAs($this, $format, $attribute, $depth);
    }

    /**
     * Presents the children of the given node in the given
     * format. If the attribute provided is a closure, we will
     * call it, providing every single node recursively. You
     * must return a string from your closure which will be
     * used as the output for that node when presenting.
     *
     * @param string $format
     * @param string|Closure $attribute
     * @param int $depth
     * @return mixed
     */
    public function presentChildrenAs($format, $attribute, $depth = 0)
    {
        return static::$presenter->presentChildrenAs($this, $format, $attribute, $depth);
    }

    /**
     * Creates a worker instance for the model.
     *
     * @return WorkerInterface
     */
    public function createWorker()
    {
        $class = '\\'.ltrim($this->worker, '\\');

        return new $class($this->getConnection(), $this);
    }

    /**
     * Sets the wroker to be used by the model.
     *
     * @param $worker
     * @return void
     */
    public function setWorker($worker)
    {
        $this->worker = $worker;
    }

    /**
     * Convert the model instance to an array.
     *
     * @return array
     */
    public function toArray()
    {
        $attributes = $this->attributesToArray();
        $attributes['children'] = [];

        foreach ($this->children as $child) {
            $attributes['children'][] = $child->toArray();
        }

        return array_merge($attributes, $this->relationsToArray());
    }

    /**
     * Loads a tree.
     *
     * @param int $depth
     * @param Closure $callback
     * @return array
     */
    protected function loadTree($depth = 0, Closure $callback = null)
    {
        $tree = $this->createWorker()->tree($this, $depth, $callback);

        // The tree method from the worker is none-the-wiser
        // to whether we are retrieving a root node or not. If
        // we only have one child, it will therefore return a
        // singular object. We'll ensure we're actually returning
        // an array.
        if (! is_array($tree)) {
            $tree = [$tree];
        }

        return $tree;
    }

    /**
     * Returns a collection of all nodes in a flat array.
     *
     * @param int $tree
     * @return \Illuminate\Database\Eloquent\Collection
     */
    public static function allFlat($tree = null)
    {
        $static = new static;
        $nodes = $static->createWorker()->allFlat($tree);

        return $static->newCollection($nodes);
    }

    /**
     * Returns a collection of all root nodes.
     *
     * @return \Illuminate\Database\Eloquent\Collection
     */
    public static function allRoot()
    {
        $static = new static;
        $root = $static->createWorker()->allRoot();

        return $static->newCollection($root);
    }

    /**
     * Returns a collection of all leaf nodes.
     *
     * @param ind $tree
     * @return \Illuminate\Database\Eloquent\Collection
     */
    public static function allLeaf($tree = null)
    {
        $static = new static;
        $leaf = $static->createWorker()->allLeaf($tree);

        return $static->newCollection($leaf);
    }

    /**
     * Sets the presenter to be used by all Eloquent nodes.
     *
     * @param Presenter $presenter
     * @return void
     */
    public static function setPresenter(Presenter $presenter)
    {
        static::$presenter = $presenter;
    }

    /**
     * Gets the presenter used by all Eloquent nodes.
     *
     * @return Presenter
     */
    public static function getPresenter()
    {
        return static::$presenter;
    }

    /**
     * Unsets the presenter instance.
     *
     * @return void
     */
    public static function unsetPresenter()
    {
        static::$presenter = null;
    }

    public function getParentId()
    {
        if ($this->getDepth() == 0) {
            // Node is root node
            return 0;
        }

        return $this->getParent()->id;
    }

    /**
     * Handle dynamic method calls into the method.
     *
     * @param string $method
     * @param array $parameters
     * @return mixed
     */
    public function __call($method, $parameters)
    {
        // Account for dynamic calls to a the presenter instance
        if (starts_with($method, 'presentAs')) {
            array_unshift($parameters, lcfirst(substr($method, 9)));

            return call_user_func_array([$this, 'presentAs'], $parameters);
        }
        if (starts_with($method, 'presentChildrenAs')) {
            array_unshift($parameters, lcfirst(substr($method, 17)));

            return call_user_func_array([$this, 'presentChildrenAs'], $parameters);
        }

        return parent::__call($method, $parameters);
    }
}