HEX
Server: Apache
System: Linux srv-plesk28.ps.kz 5.14.0-284.18.1.el9_2.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Jun 29 17:06:27 EDT 2023 x86_64
User: greencl1 (10085)
PHP: 8.1.33
Disabled: apache_setenv,dl,eval,exec,openlog,passthru,pcntl_exec,pcntl_fork,popen,posix_getpwuid,posix_kill,posix_mkfifo,posix_setpgid,posix_setsid,posix_setuid,proc_close,proc_get_status,proc_nice,proc_open,proc_terminate,shell_exec,socket_create,socket_create_listen,socket_create_pair,syslog,system,socket_listen,stream_socket_server
Upload Files
File: /var/www/vhosts/greenclinic.kz/test.greenclinic.kz/vendor/october/rain/src/Database/DataFeed.php
<?php namespace October\Rain\Database;

use Db;
use Str;
use Closure;
use Illuminate\Database\Eloquent\Model as EloquentModel;
use Exception;

/**
 * Model Data Feed class.
 *
 * Combine various models in to a single feed.
 *
 * @package october\database
 * @author Alexey Bobkov, Samuel Georges
 */
class DataFeed
{

    /**
     * @var string The attribute to use for each model tag name.
     */
    public $tagVar = 'tag_name';

    /**
     * @var string An alias to use for each entries timestamp attribute.
     */
    public $sortVar = 'order_by_column_name';

    /**
     * @var string Default sorting attribute.
     */
    public $sortField = 'id';

    /**
     * @var string Default sorting direction.
     */
    public $sortDirection = 'desc';

    /**
     * @var string Limits the number of results.
     */
    public $limitCount = null;

    /**
     * @var string Set the limit offset.
     */
    public $limitOffset = null;

    /**
     * @var array Model collection pre-query.
     */
    protected $collection = [];

    /**
     * @var Builder Cache containing the generic collection union query.
     */
    protected $queryCache;

    /**
     * @var bool
     */
    public $removeDuplicates = false;

    /**
     * Add a new Builder to the feed collection
     */
    public function add($tag, $item, $orderBy = null)
    {
        if ($item instanceof Closure) {
            $item = call_user_func($item);
        }

        if (!$item)
            return;

        $keyName = $item instanceof EloquentModel
            ? $item->getKeyName()
            : $item->getModel()->getKeyName();

        $this->collection[$tag] = compact('item', 'orderBy', 'keyName');

        // Reset the query cache
        $this->queryCache = null;

        return $this;
    }

    /**
     * Count the number of results from the generic union query
     */
    public function count()
    {
        $query = $this->processCollection();
        $bindings = $query->bindings;
        $records = sprintf("(%s) as records", $query->toSql());
        $result = Db::table(Db::raw($records))->selectRaw("COUNT(*) as total");

        // Set the bindings, if present
        foreach ($bindings as $type => $params) {
            $result = $result->setBindings($params, $type);
        }
        
        $result = $result->first();
        return $result->total;
    }

    /**
     * Executes the generic union query and eager loads the results in to the added models
     */
    public function get()
    {
        $query = $this->processCollection();

        /*
         * Apply constraints to the entire query
         */
        $query->limit($this->limitCount);

        if ($this->limitOffset) {
            $query->offset($this->limitOffset);
        }

        $query->orderBy($this->sortVar, $this->sortDirection);
        $records = $query->get();

        /*
         * Build a collection of class names and IDs needed
         */
        $mixedArray = [];
        foreach ($records as $record) {
            $tagName = $record->{$this->tagVar};
            $mixedArray[$tagName][] = $record->id;
        }

        /*
         * Eager load the data collection
         */
        $collectionArray = [];
        foreach ($mixedArray as $tagName => $ids) {
            $obj = $this->getModelByTag($tagName);
            $keyName = $this->getKeyNameByTag($tagName);
            $collectionArray[$tagName] = $obj->whereIn($keyName, $ids)->get();
        }

        /*
         * Now load the data objects in to a final array
         */
        $dataArray = [];
        foreach ($records as $record) {
            $tagName = $record->{$this->tagVar};

            $obj = $collectionArray[$tagName]->find($record->id);
            $obj->{$this->tagVar} = $tagName;

            $dataArray[] = $obj;
        }

        return new Collection($dataArray);
    }

    /**
     * Returns the SQL expression used in the generic union
     */
    public function toSql()
    {
        $query = $this->processCollection();
        return $query->toSql();
    }

    /**
     * Sets the default sorting field and direction.
     */
    public function orderBy($field, $direction = null)
    {
        $this->sortField = $field;
        if ($direction) {
            $this->sortDirection = $direction;
        }

        return $this;
    }

    /**
     * Limits the number of results displayed.
     */
    public function limit($count, $offset = null)
    {
        $this->limitCount = $count;
        if ($offset) {
            $this->limitOffset = $offset;
        }

        return $this;
    }

    //
    // Internals
    //

    /**
     * Creates a generic union query of each added collection
     */
    protected function processCollection()
    {
        if ($this->queryCache !== null)
            return $this->queryCache;

        $lastQuery = null;
        foreach ($this->collection as $tag => $data) {
            extract($data);
            $cleanQuery = clone $item->getQuery();
            $model = $item->getModel();

            $sorting = $model->getTable() . '.';
            $sorting .= $orderBy ?: $this->sortField;
            
            // Flush the select and add ID and tag
            $conditionalTagSelect = (Db::connection()->getDriverName() === 'pgsql') ?
                "CAST('%s' as text) as %s" :
                "'%s' as %s";
            $idSelect = sprintf("%s as id", $keyName);
            $tagSelect = sprintf($conditionalTagSelect, $tag, $this->tagVar);
            $sortSelect = sprintf("%s as %s", $sorting, $this->sortVar);

            $cleanQuery = $cleanQuery->select(Db::raw($idSelect))
                ->addSelect(Db::raw($tagSelect))
                ->addSelect(Db::raw($sortSelect));
            
            // Union this query with the previous one
            if ($lastQuery) {
                if ($this->removeDuplicates)
                    $cleanQuery = $lastQuery->union($cleanQuery);
                else
                    $cleanQuery = $lastQuery->unionAll($cleanQuery);
            }

            $lastQuery = $cleanQuery;
        }

        return $this->queryCache = $lastQuery;
    }

    /**
     * Returns a prepared model by its tag name.
     * @return Model
     */
    protected function getModelByTag($tag)
    {
        extract($this->getDataByTag($tag));
        return $item;
    }

    /**
     * Returns a model key name by its tag name.
     * @return Model
     */
    protected function getKeyNameByTag($tag)
    {
        extract($this->getDataByTag($tag));
        return $keyName;
    }

    /**
     * Returns a data stored about an item by its tag name.
     * @return array
     */
    protected function getDataByTag($tag)
    {
        if (!$data = array_get($this->collection, $tag)) {
            throw new Exception('Unable to find model in collection with tag: ' . $tag);
        }

        return $data;
    }
}