__  __    __   __  _____      _            _          _____ _          _ _ 
 |  \/  |   \ \ / / |  __ \    (_)          | |        / ____| |        | | |
 | \  / |_ __\ V /  | |__) | __ ___   ____ _| |_ ___  | (___ | |__   ___| | |
 | |\/| | '__|> <   |  ___/ '__| \ \ / / _` | __/ _ \  \___ \| '_ \ / _ \ | |
 | |  | | |_ / . \  | |   | |  | |\ V / (_| | ||  __/  ____) | | | |  __/ | |
 |_|  |_|_(_)_/ \_\ |_|   |_|  |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1
 if you need WebShell for Seo everyday contact me on Telegram
 Telegram Address : @jackleet
        
        
For_More_Tools: Telegram: @jackleet | Bulk Smtp support mail sender | Business Mail Collector | Mail Bouncer All Mail | Bulk Office Mail Validator | Html Letter private



Upload:

Command:

[email protected]: ~ $
<?php
/**
 * @package SP Page Builder
 * @author JoomShaper http://www.joomshaper.com
 * @copyright Copyright (c) 2010 - 2024 JoomShaper
 * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 or later
 */

namespace JoomShaper\SPPageBuilder\DynamicContent;

defined('_JEXEC') or die;

use Closure;
use RuntimeException;
use Throwable;
use Joomla\CMS\Factory;
use Joomla\Database\DatabaseDriver;
use JoomShaper\SPPageBuilder\DynamicContent\Supports\Arr;
use JoomShaper\SPPageBuilder\DynamicContent\Concerns\HasEagerLoading;
use JoomShaper\SPPageBuilder\DynamicContent\Constants\Operators;
use JoomShaper\SPPageBuilder\DynamicContent\Supports\Expression;

class QueryBuilder
{
    use HasEagerLoading;

    /**
     * The database driver instance.
     *
     * @var DatabaseDriver
     * @since 5.5.0
     */
    private $db;

    /**
     * The database query instance.
     *
     * @var DatabaseQuery
     * @since 5.5.0
     */
    private $query;

    /**
     * The limit of the query.
     *
     * @var int
     * @since 5.5.0
     */
    private $limit = 0;

    /**
     * The offset of the query.
     *
     * @var int
     * @since 5.5.0
     */
    private $offset = 0;

    /**
     * The columns of the query.
     *
     * @var array
     * @since 5.5.0
     */
    private $columns = [];

    /**
     * The model instance.
     *
     * @var Model
     * @since 5.5.0
     */
    protected $model;

    /**
     * The data of the query.
     *
     * @var array
     * @since 5.5.0
     */
    protected $data;

    /**
     * The static database driver instance.
     *
     * @var DatabaseDriver
     * @since 5.5.0
     */
    protected static $staticDb = null;

    /**
     * The operators that do not require a value.
     *
     * @var array
     * @since 5.5.0
     */
    protected const NO_VALUE_OPERATORS = [Operators::IS_NULL, Operators::IS_NOT_NULL];

    /**
     * The operators that require a value.
     *
     * @var array
     * @since 5.5.0
     */
    protected const IN_OPERATORS = [Operators::IN, Operators::NOT_IN];

    /**
     * The constructor of the class.
     *
     * @param Model $model
     * @since 5.5.0
     */
    public function __construct(Model $model)
    {
        $this->db = Factory::getDbo();
        $this->query = $this->db->getQuery(true);
        $this->model = $model;
        $this->columns = [];
    }

    public function setModel(Model $model)
    {
        $this->model = $model;
        return $this;
    }

    /**
     * Get the database query instance.
     *
     * @return DatabaseQuery
     * @since 5.5.0
     */
    public function getQuery()
    {
        return $this->query;
    }

    /**
     * Get the database driver instance.
     *
     * @return DatabaseDriver
     * @since 5.5.0
     */
    public function getDatabase()
    {
        return $this->db;
    }

    /**
     * Get the static database driver instance.
     *
     * @return DatabaseDriver
     * @since 5.5.0
     */
    protected static function getStaticDb()
    {
        if (is_null(self::$staticDb)) {
            self::$staticDb = Factory::getDbo();
        }

        return self::$staticDb;
    }

    /**
     * Clear the query.
     *
     * @param string $clause The clause
     * @since 5.5.0
     */
    public function clearQuery($clause = null)
    {
        if (is_null($clause)) {
            $this->query->clear();
        } elseif (is_array($clause)) {
            foreach ($clause as $item) {
                $this->query->clear($item);
            }
        } else {
            $this->query->clear($clause);
        }

        return $this;
    }

    /**
     * Get the prefix of the query.
     *
     * @return string
     * @since 5.5.0
     */
    public function getPrefix()
    {
        return $this->model->getName();
    }

    /**
     * Quote the column name with the prefix.
     *
     * @param string $column
     * @param string $as
     * 
     * @return string
     * @since 5.5.0
     */
    public function quoteNameWithPrefix($column, $as = null)
    {   
        $hasPrefix = strpos($column, '.') !== false;

        if ($hasPrefix) {
            return $this->db->quoteName($column, $as);
        }

        $prefix = $this->getPrefix();
        $column = $prefix . '.' . $column;

        return $this->db->quoteName($column, $as);
    }

    /**
     * Quote the column name.
     *
     * @param string $column
     * @param string $as
     * @return string
     * @since 5.5.0
     */
    public function quoteName($column, $as = null)
    {
        return $this->db->quoteName($column, $as);
    }

    /**
     * Quote the value.
     *
     * @param string $value
     * @return string
     * @since 5.5.0
     */
    public function quote($value)
    {
        return $this->db->quote($value);
    }

    /**
     * Set the limit of the query for getting a limited number of records.
     *
     * @param int $limit
     * 
     * @return self
     * @since 5.5.0
     */
    public function take(int $limit)
    {
        $this->limit = $limit;
        return $this;
    }

    /**
     * Set the offset of the query for skipping a number of records.
     *
     * @param int $offset
     * 
     * @return self
     * @since 5.5.0
     */
    public function skip(int $offset = 0)
    {
        $this->offset = $offset;
        return $this;
    }

    /**
     * Set the columns of the query.
     *
     * @param array $columns
     * 
     * @return self
     * @since 5.5.0
     */
    public function setColumns(array $columns = [])
    {
        $this->columns = $columns;
        return $this;
    }

    /**
     * Get the columns of the query.
     *
     * @return array
     * @since 5.5.0
     */
    public function getColumns()
    {
        return $this->columns;
    }

    /**
     * Eager load the relations of the query.
     *
     * @param string|array $relations
     * 
     * @return self
     * @since 5.5.0
     */
    public function with($relations)
    {
        return $this->setEagerRelations($relations);
    }
    /**
     * Performing the AND where conditions.
     *
     * @param array $conditions
     *
     * @return self
     * @since 5.5.0
     */
    public function where($column, $operator = Operators::EQUAL, $value = null)
    {   
        $this->query->where($this->buildWhere($column, $operator, $value));
        return $this;
    }

    /**
     * Performing the NOT where conditions.
     *
     * @param string $column
     * @param mixed $value
     *
     * @return self
     * @since 5.5.0
     */
    public function whereNot($column, $value)
    {
        return $this->where($column, Operators::NOT_EQUAL, $value);
    }

    /**
     * Performing the greater than where conditions.
     *
     * @param string $column
     * @param mixed $value
     *
     * @return self
     * @since 5.5.0
     */
    public function whereGreaterThan($column, $value)
    {
        return $this->where($column, Operators::GREATER_THAN, $value);
    }

    /**
     * Performing the less than where conditions.
     *
     * @param string $column
     * @param mixed $value
     *
     * @return self
     * @since 5.5.0
     */
    public function whereLessThan($column, $value)
    {
        return $this->where($column, Operators::LESS_THAN, $value);
    }

    /**
     * Performing the greater than or equal where conditions.
     *
     * @param string $column
     * @param mixed $value
     *
     * @return self
     * @since 5.5.0
     */
    public function whereGreaterThanOrEqual($column, $value)
    {
        return $this->where($column, Operators::GREATER_THAN_OR_EQUAL, $value);
    }

    /**
     * Performing the less than or equal where conditions.
     *
     * @param string $column
     * @param mixed $value
     *
     * @return self
     * @since 5.5.0
     */
    public function whereLessThanOrEqual($column, $value)
    {
        return $this->where($column, Operators::LESS_THAN_OR_EQUAL, $value);
    }

    /**
     * Performing the IN where conditions.
     *
     * @param string $column
     * @param array $values
     *
     * @return self
     * @since 5.5.0
     */
    public function whereIn($column, array $values)
    {
        return $this->where($column, Operators::IN, $values);
    }

    /**
     * Performing the NOT IN where conditions.
     *
     * @param string $column
     * @param array $values
     *
     * @return self
     * @since 5.5.0
     */
    public function whereNotIn($column, array $values)
    {
        return $this->where($column, Operators::NOT_IN, $values);
    }

    /**
     * Performing the IS NULL where conditions.
     *
     * @param string $column
     *
     * @return self
     * @since 5.5.0
     */
    public function whereNull($column)
    {
        return $this->where($column, Operators::IS_NULL);
    }

    /**
     * Performing the IS NOT NULL where conditions.
     *
     * @param string $column
     *
     * @return self
     * @since 5.5.0
     */
    public function whereNotNull($column)
    {
        return $this->where($column, Operators::IS_NOT_NULL);
    }

    /**
     * Performing the BETWEEN where conditions.
     *
     * @param string $column
     * @param array $values
     *
     * @return self
     * @since 5.5.0
     */
    public function whereBetween($column, array $values)
    {
        return $this->where($column, Operators::BETWEEN, $values);
    }

    /**
     * Performing the LIKE where conditions.
     *
     * @param string $column
     * @param mixed $value
     *
     * @return self
     * @since 5.5.0
     */
    public function whereLike($column, $value)
    {
        return $this->where($column, Operators::LIKE, $value);
    }

    /**
     * Performing the NOT LIKE where conditions.
     *
     * @param string $column
     * @param mixed $value
     *
     * @return self
     * @since 5.5.0
     */
    public function whereNotLike($column, $value)
    {
        return $this->where($column, Operators::NOT_LIKE, $value);
    }

    /**
     * Performing the EXISTS where conditions.
     *
     * @param Closure $callback
     *
     * @return self
     * @since 5.5.0
     */
    public function whereExists(Closure $callback)
    {
        $db = $this->getDatabase();
        $query = $callback($db);
        $this->query->where('EXISTS (' . $query->__toString() . ')');

        return $this;
    }

    /**
     * Performing the raw where conditions.
     *
     * @param Closure $callback
     *
     * @return self
     * @since 5.5.0
     */
    public function whereRaw(Closure $callback)
    {
        $db = $this->getDatabase();
        $queryString = $callback($db);
        $this->query->where($queryString);
        return $this;
    }

    /**
     * Performing the OR where conditions.
     *
     * @param array $conditions
     *
     * @return self
     * @since 5.5.0
     */
    public function orWhere($column, $operator = Operators::EQUAL, $value = null)
    {
        $this->query->orWhere($this->buildWhere($column, $operator, $value));
        return $this;
    }

    /**
     * Performing the raw where conditions.
     *
     * @param Closure $callback
     *
     * @return self
     * @since 5.5.0
     */
    public function rawQuery(Closure $callback)
    {
        return tap($this, $callback);
    }

    /**
     * Set the columns of the query.
     *
     * @param array $columns
     * 
     * @return self
     * @since 5.5.0
     */
    public function select($columns)
    {
        if (!is_array($columns)) {
            $columns = [$columns];
        }

        $columns = array_map(function ($column, $key) {
            if (is_numeric($key)) {
                return $this->quoteNameWithPrefix($column);
            }

            return $this->quoteNameWithPrefix($column, $key);
        }, $columns, array_keys($columns));

        $this->query->select($columns);
        return $this;
    }

    /**
     * Find the record by the primary key value.
     *
     * @param mixed $primaryKeyValue
     *
     * @return Model
     * @since 5.5.0
     */
    public function find($primaryKeyValue)
    {
        return $this->where($this->model->getPrimaryKey(), $primaryKeyValue)->first();
    }

    /**
     * Set the order of the query.
     *
     * @param string $column
     * @param string $direction
     * 
     * @return self
     * @since 5.5.0
     */
    public function orderBy($column, $direction = 'ASC')
    {
        $this->query->order($this->db->escape($this->quoteNameWithPrefix($column)) . ' ' . strtoupper($direction));

        return $this;
    }

    /**
     * Join the related model to the query.
     *
     * @param string $related
     * @param string $foreignKey
     * @param string $localKey
     * @param string $type
     * 
     * @return self
     * @since 5.5.0
     */
    public function join($related, $foreignKey = null, $localKey = null, $type = 'INNER')
    {
        $relatedModel = new $related();
        $relatedQueryProvider = new static($relatedModel);
        $foreignKey = $foreignKey ?? $this->model->getName() . '_' . $relatedModel->getPrimaryKey();
        $localKey = $localKey ?? $relatedModel->getPrimaryKey();

        $this->query->join(
            $type,
            $this->db->quoteName($relatedModel->getTable(), $relatedModel->getName()) . ' ON (' .
            $relatedQueryProvider->quoteNameWithPrefix($foreignKey) .  ' = ' . $this->quoteNameWithPrefix($localKey) . ')'
        );

        return $this;
    }

    /**
     * Join the related model to the query as a left join.
     *
     * @param string $related
     * @param string $foreignKey
     * @param string $localKey
     * 
     * @return self
     * @since 5.5.0
     */
    public function leftJoin($related, $foreignKey = null, $localKey = null)
    {
        return $this->join($related, $foreignKey, $localKey, 'LEFT');
    }

    /**
     * Join the related model to the query as a right join.
     *
     * @param string $related
     * @param string $foreignKey
     * @param string $localKey
     * 
     * @return self
     * @since 5.5.0
     */
    public function rightJoin($related, $foreignKey = null, $localKey = null)
    {
        return $this->join($related, $foreignKey, $localKey, 'RIGHT');
    }

    /**
     * Join the related model to the query as a full join.
     *
     * @param string $related
     * @param string $foreignKey
     * @param string $localKey
     * 
     * @return self
     * @since 5.5.0
     */
    public function fullJoin($related, $foreignKey = null, $localKey = null)
    {
        return $this->join($related, $foreignKey, $localKey, 'FULL');
    }

    /**
     * Join the related model to the query as an inner join.
     *
     * @param string $related
     * @param string $foreignKey
     * @param string $localKey
     * 
     * @return self
     * @since 5.5.0
     */
    public function innerJoin($related, $foreignKey = null, $localKey = null)
    {
        return $this->join($related, $foreignKey, $localKey, 'INNER');
    }

    /**
     * Get the data records from the database.
     *
     * @param array $columns
     * @return array
     * @since 5.5.0
     */
    public function get(array $columns = [])
    {
        $this->setColumns($columns);
        $this->prepareQuery();
        $results = $this->db->loadObjectList();

        if (empty($results)) {
            return [];
        }

        $models = array_map([$this->model, 'newInstance'], $results);

        if ($this->hasEagerRelations()) {
            return $this->eagerLoadRelations($models);
        }

        return $models;
    }

    /**
     * Get the first record from the database.
     *
     * @param array $columns
     * 
     * @return Model
     * @since 5.5.0
     */
    public function first(array $columns = [])
    {
        $this->setColumns($columns);
        $this->prepareQuery();

        $data = $this->db->loadObject();
        $this->model->setItem($data);

        // No need to load relations eagerly if the model is empty
        if ($this->model->isEmpty()) {
            return $this->model;
        }

        if ($this->hasEagerRelations()) {
            $this->eagerLoadRelations([$this->model]);
        }

        return $this->model;
    }

    /**
     * Check if the record exists.
     *
     * @return bool
     * @since 5.5.0
     */
    public function exists()
    {
        return $this->count() > 0;
    }

    /**
     * Get the total number of records from the database.
     *
     * @return int
     * @since 5.5.0
     */
    public function count()
    {
        $this->clearQuery([
            'select',
            'from',
            'limit',
            'offset',
        ]);

        $primaryKey = $this->model->getPrimaryKey();
        $this->buildSelect("COUNT({$primaryKey}) as total");
        $this->buildFrom($this->model->getTable());

        try
        {
            $this->db->setQuery($this->query);
            $this->db->execute();
        }
        catch (Throwable $error)
        {
            return 0;
        }

        return $this->db->loadResult();
    }

    /**
     * Get the total number of records from the database for pagination.
     *
     * @return int
     * @since 5.5.0
     */
    public function runPaginationCountQuery()
    {
        $new = $this->newInstance();
        $new->query = $this->cloneWithout(['select', 'from', 'limit', 'offset', 'join']);

        $primaryKey = $new->model->getPrimaryKey();
        $new->buildSelect("COUNT({$primaryKey}) as total");
        $new->buildFrom($new->model->getTable());

        try
        {
            $new->db->setQuery($new->query);
            $new->db->execute();
        }
        catch (Throwable $error)
        {
            return 0;
        }

        return $new->db->loadResult();
    }

    /**
     * Get the paginated data from the database.
     *
     * @param int $perPage
     * @param int $currentPage
     * @param array $columns
     *
     * @return array
     * @since 5.5.0
     */
    public function paginate($perPage = 10, $currentPage = 1, array $columns = [])
    {
        $this->take($perPage);
        $this->skip(($currentPage - 1) * $perPage);
        $results = $this->get($columns);
        $count = $this->runPaginationCountQuery();

        return [
            'data' => $results,
            'total' => $count,
            'per_page' => $perPage,
            'current_page' => $currentPage,
            'last_page' => ceil($count / $perPage),
            'total_pages' => ceil($count / $perPage),
        ];
    }

    /**
     * Create a new record in the database.
     *
     * @param array $data
     *
     * @return int
     * @since 5.5.0
     */
    public function create(array $data)
    {
        // If the model has an ordering key, set the ordering value to the latest ordering value + 1
        if (!empty($this->model->getOrderingKey())) {
            $data[$this->model->getOrderingKey()] = $this->getLatestOrderingValue() + 1;
        }

        $this->query->insert($this->db->quoteName($this->model->getTable()))
            ->columns($this->getRecordColumns($data))
            ->values($this->prepareInsertionValue($data));

        try
        {
            $this->db->setQuery($this->query);
            $this->db->execute();
            $insertId = $this->db->insertId();

            if ($this->model->hasAsset()) {
                $this->model->newQuery()
                    ->find($insertId)
                    ->manageAsset();
            }

            return $insertId;
        }
        catch (Throwable $error)
        {
            throw $error;
        }
    }

    /**
     * Create multiple records in the database.
     *
     * @param array $data
     *
     * @return int
     * @since 5.5.0
     */
    public function createMany(array $data)
    {
        if (!empty($orderingKey = $this->model->getOrderingKey())) {
            $lastOrderingValue = $this->getLatestOrderingValue();

            foreach ($data as &$item) {
                $item[$orderingKey] = ++$lastOrderingValue;
            }

            unset($item);
        }

        $this->query
            ->insert($this->db->quoteName($this->model->getTable()))
            ->columns($this->db->quoteName($this->getRecordColumns($data)));

        $values = Arr::make($data)->map(function($record) {
            return $this->prepareInsertionValue($record);
        });

        $this->query->values($values->toArray());

        try
        {
            $this->db->setQuery($this->query);
            $this->db->execute();
        }
        catch (Throwable $error)
        {
            throw $error;
        }

        return $this->db->getAffectedRows();
    }

    /**
     * Update a record in the database.
     *
     * @param array|callable $data
     *
     * @return bool
     * @since 5.5.0
     */
    public function update($data)
    {
        if (is_callable($data)) {
            $fields = $data($this);
        } else {
            $fields = $this->prepareUpdateValues($data);
        }

        $this->query->update(
            $this->db->quoteName(
                $this->model->getTable(),
                $this->model->getName()
            )
        )->set($fields);

        try
        {
            $this->db->setQuery($this->query);
            return $this->db->execute();
        }
        catch (Throwable $error)
        {
            throw $error;
        }
    }

    /**
     * Delete a record from the database.
     *
     * @return bool
     * @since 5.5.0
     */
    public function delete()
    {
        $this->query->delete(
            $this->quoteName(
                $this->model->getTable(),
                $this->hasJoinClause() ? $this->model->getName() : null
            )
        );

        if (!$this->hasJoinClause()) {
            $this->removeAliasFromWhereClauses();
        }

        try
        {
            $this->db->setQuery($this->query);
            return $this->db->execute();
        }
        catch (Throwable $error)
        {
            throw $error;
        }

        return false;
    }

    /**
     * Begin the transaction.
     *
     * @return void
     * @since 5.5.0
     */
    public static function beginTransaction()
    {
        $db = static::getStaticDb();
        $db->transactionStart();
    }

    /**
     * Commit the transaction.
     *
     * @return void
     * @since 5.5.0
     */
    public static function commit()
    {
        $db = static::getStaticDb();
        $db->transactionCommit();
    }

    /**
     * Rollback the transaction.
     *
     * @return void
     * @since 5.5.0
     */
    public static function rollback()
    {
        $db = static::getStaticDb();
        $db->transactionRollback();
    }

    /**
     * Execute a callback within a transaction.
     *
     * @param callable $callback
     * 
     * @return void
     * @since 5.5.0
     */
    public static function transaction(callable $callback)
    {
        static::beginTransaction();

        try
        {
            $callback();
        }
        catch (Throwable $error)
        {
            static::rollback();
            throw $error;
        }

        static::commit();
    }

    /**
     * Create a raw expression.
     *
     * @param mixed $value
     *
     * @return Expression
     * @since 5.5.0
     */
    public static function raw($value)
    {
        return new Expression($value);
    }

    /**
     * Check if the query has a join clause.
     *
     * @return bool
     * @since 5.5.1
     */
    protected function hasJoinClause()
    {
        return !empty($this->query->join) && count($this->query->join->getElements()) > 0;
    }

    /**
     * Remove the alias from the where clauses.
     *
     * @return self
     * @since 5.5.1
     */
    protected function removeAliasFromWhereClauses()
    {
        $whereElements = $this->query->where->getElements();
        $whereElements = Arr::make($whereElements);

        $whereElementsWithoutAlias = $whereElements->map(function($element) {
            $dotIndex = strpos($element, '.');

            if ($dotIndex !== false) {
                return substr($element, $dotIndex + 1);
            }

            return $element;
        });

        $this->query->clear('where');

        foreach ($whereElementsWithoutAlias as $whereClause) {
            $this->query->where($whereClause);
        }

        return $this;
    }

    /**
     * Set the table of the query.
     *
     * @param string $table
     * @since 5.5.0
     */
    protected function buildFrom(string $table)
    {
        $this->query->from(
            $this->db->quoteName($table, $this->model->getName())
        );

        return $this;
    }

    /**
     * Rearrange the select clause.
     * Make sure the '*' is always the first element.
     *
     * @return self
     * @since 5.5.0
     */
    protected function rearrangeSelectClause()
    {
        $select = $this->query->select->getElements();
        $elements = Arr::make($select);

        $starIndex = $elements->findIndex(function ($element) {
            return strpos($element, '*') !== false;
        });

        if ($starIndex > -1) {
            $starElement = $elements[$starIndex];
            unset($elements[$starIndex]);
            $elements->prepend($starElement);
        }

        $this->clearQuery('select');
        $this->query->select($elements->toArray());

        return $this;
    }

    /**
     * Build the select query.
     *
     * @param array $columns
     * @since 5.5.0
     */
    protected function buildSelect($columns)
    {
        if (empty($columns)) {
            $this->query->select($this->model->getName() . '.*');
            return $this->rearrangeSelectClause();
        }

        if (!is_array($columns)) {
            $columns = [$columns];
        }

        $this->query->select($columns);
        return $this->rearrangeSelectClause();
    }

    /**
     * Build the where query using Joomla quoteName and quote methods.
     *
     * @param array $conditions
     * @since 5.5.0
     */
    protected function buildWhere($column, $operator = Operators::EQUAL, $value = null, $boolean = 'AND')
    {
        // Handle array format: ['name' => 'value', 'age' => 20]
        if (is_array($column) && !isset($column[0])) {
            $conditions = [];

            foreach ($column as $key => $item) {
                $conditions[] = $this->quoteNameWithPrefix($key) . ' ' . Operators::EQUAL . ' ' . $this->serialize($item);
            }

            return implode(" $boolean ", $conditions);
        }

        // Handle operators that do not require a value, e.g. IS NULL, IS NOT NULL
        if (in_array(strtoupper($operator), static::NO_VALUE_OPERATORS, true)) {
            return $this->quoteNameWithPrefix($column) . ' ' . $operator;
        }

        // Handle format: where('name', 'value')
        if (is_null($value)) {
            $value = $operator;
            $operator = Operators::EQUAL;
        }

        // Handle IN or NOT IN conditions
        if (in_array(strtoupper($operator), static::IN_OPERATORS, true)) {
            if (!is_array($value) || empty($value)) {
                throw new RuntimeException(sprintf('The %s operator requires a non-empty array.', strtoupper($operator)));
            }

            $quotedValues = array_map([$this, 'serialize'], $value);
            $value = '(' . implode(',', $quotedValues) . ')';
            return $this->quoteNameWithPrefix($column) . " {$operator} " . $value;
        }

        if (strtoupper($operator) === Operators::BETWEEN) {
            if (!is_array($value) || count($value) !== 2) {
                throw new RuntimeException('The BETWEEN operator requires an array with two values.');
            }

            $operator = Operators::BETWEEN;
            return $this->quoteNameWithPrefix($column) . " {$operator} " . $this->serialize($value[0]) . ' AND ' . $this->serialize($value[1]);
        }

        // Handle where('name', 'like', '%value%')
        return $this->quoteNameWithPrefix($column) . ' ' . $operator . ' ' . $this->serialize($value);
    }

    /**
     * Prepare the query for getting data from database.
     *
     * @return self
     * @since 5.5.0
     */
    protected function prepareQuery()
    {
        $this->buildSelect($this->getColumns());
        $this->buildFrom($this->model->getTable());

        $this->query->setLimit($this->limit, $this->offset);
        $this->db->setQuery($this->query);
        return $this;
    }

    /**
     * Get the record columns.
     *
     * @param array $data The data
     *
     * @return array
     * @since 5.5.0
     */
    protected function getRecordColumns(array $data)
    {
        return !Arr::isAssociative($data) && !empty($data) ? array_keys($data[0]) : array_keys($data);
    }

    /**
     * Serialize the value.
     *
     * @param mixed $value The value
     *
     * @return mixed
     * @since 5.5.0
     */
    protected function serialize($value)
    {
        if (is_null($value)) {
            return 'NULL';
        }

        if (is_integer($value) || is_float($value)) {
            return $value;
        }

        if (is_numeric($value)) {
            $isFloat = strpos(strval($value), '.') !== false;
            return $isFloat ? floatval($value) : intval($value);
        }

        if (is_bool($value)) {
            return (int) $value;
        }

        return $this->db->quote($value);
    }

    /**
     * Serialize the values.
     *
     * @param array $data The data
     *
     * @return Arr
     * @since 5.5.0
     */
    protected function serializeValues(array $data)
    {
        return Arr::make($data)->map(function($item) {
            return $this->serialize($item);
        });
    }

    /**
     * Prepare the insertion value.
     *
     * @param array $data The data
     *
     * @return string
     * @since 5.5.0
     */
    protected function prepareInsertionValue(array $data)
    {
        return $this->serializeValues($data)->join(',');
    }

    /**
     * Prepare the update values.
     *
     * @param array $data The data
     *
     * @return array
     * @since 5.5.0
     */
    protected function prepareUpdateValues(array $data)
    {
        $data = Arr::make($data);
        return $data->map(function($item, $key) {
            $value = $item instanceof Expression ? (string) $item : $this->serialize($item);
            return $this->quoteNameWithPrefix($key) . ' = ' . $value;
        })->toArray();
    }

    /**
     * Get the latest ordering value.
     *
     * @return int
     * @since 5.5.0
     */
    protected function getLatestOrderingValue()
    {
        $instance = $this->model->newInstance();
        $orderingKey = $this->model->getOrderingKey();

        return $instance->orderBy($orderingKey, 'DESC')->first([$orderingKey])->$orderingKey ?? 0;
    }

    /**
     * Create a new instance of the class.
     *
     * @return static
     * @since 5.5.0
     */
    protected function newInstance()
    {
        return new static($this->model);
    }

    /**
     * Clone the query without the specified clauses.
     *
     * @param array $without
     * @return DatabaseQuery
     * @since 5.5.0
     */
    protected function cloneWithout(array $without)
    {
        $query = clone $this->getQuery();

        foreach ($without as $clause) {
            $query->clear($clause);
        }

        return $query;
    }

    /**
     * Convert the query to a string.
     *
     * @return string
     * 
     * @return mixed
     * @since 5.5.0
     */
    public function __toString()
    {
        return $this->query->dump();
    }

    /**
     * Get the query string.
     *
     * @return string
     * @since 5.5.0
     */
    public function queryString()
    {
        return (string) $this->query;
    }
}

Filemanager

Name Type Size Permission Actions
Concerns Folder 0775
Constants Folder 0775
Contracts Folder 0775
Controllers Folder 0775
Exceptions Folder 0775
Http Folder 0775
Models Folder 0775
Relations Folder 0775
Services Folder 0775
Site Folder 0775
Supports Folder 0775
Controller.php File 2.8 KB 0664
DynamicContent.php File 5.15 KB 0664
Model.php File 10.96 KB 0664
QueryBuilder.php File 31.24 KB 0664
helper.php File 2.3 KB 0664
Filemanager