Current File : /home/pacjaorg/public_html/kmm/libraries/regularlabs/src/DB.php
<?php
/**
 * @package         Regular Labs Library
 * @version         23.9.3039
 * 
 * @author          Peter van Westen <info@regularlabs.com>
 * @link            https://regularlabs.com
 * @copyright       Copyright © 2023 Regular Labs All Rights Reserved
 * @license         GNU General Public License version 2 or later
 */

namespace RegularLabs\Library;

defined('_JEXEC') or die;

use Joomla\CMS\Factory as JFactory;
use Joomla\CMS\Uri\Uri as JUri;
use Joomla\Database\DatabaseDriver as JDatabaseDriver;
use Joomla\Database\DatabaseQuery as JDatabaseQuery;
use Joomla\Database\QueryInterface as JQueryInterface;

class DB
{
    static $tables = [];

    /**
     * @param JQueryInterface $query
     * @param string          $prefix
     */
    public static function addArticleIsPublishedFilters(&$query, $prefix = 'a')
    {
        $filters = self::getArticleIsPublishedFilters($prefix);

        $query->where($filters);
    }

    /**
     * Concatenate conditions using AND or OR
     *
     * @param string $glue
     * @param array  $conditions
     *
     * @return string
     */
    public static function combine($conditions = [], $glue = 'OR')
    {
        if (empty($conditions))
        {
            return '';
        }

        if ( ! is_array($conditions))
        {
            return (string) $conditions;
        }

        if (count($conditions) < 2)
        {
            return reset($conditions);
        }

        $glue = strtoupper($glue) == 'AND' ? 'AND' : 'OR';

        return '(' . implode(' ' . $glue . ' ', $conditions) . ')';
    }

    /**
     * Creat a query dump string
     *
     * @param string|JQueryInterface $query
     * @param string                 $class_prefix
     * @param string                 $caller_offset
     */
    public static function dump($query, $class_prefix = '', $caller_offset = 0)
    {
        $string = "\n" . (string) $query;
        $string = str_replace('#__', JFactory::getDbo()->getPrefix(), $string);

        Protect::protectByRegex($string, ' IN \(.*?\)');
        Protect::protectByRegex($string, ' FIELD\(.*?\)');

        $string = preg_replace('#(\n[A-Z][A-Z ]+) #', "\n\\1\n       ", $string);
        $string = str_replace(' LIMIT ', "\n\nLIMIT ", $string);
        $string = str_replace(' ON ', "\n    ON ", $string);
        $string = str_replace(' OR ', "\n    OR ", $string);
        $string = str_replace(' AND ', "\n   AND ", $string);
        $string = str_replace('`,', "`,\n       ", $string);

        Protect::unprotect($string);

        echo "\n<pre>==============================================================================\n";
        echo self::getQueryComment($class_prefix, $caller_offset) . "\n";
        echo "-----------------------------------------------------------------------------------\n";
        echo trim($string);
        echo "\n===================================================================================</pre>\n";
    }

    /**
     * @return  JDatabaseDriver
     */
    public static function get()
    {
        return JFactory::getDbo();
    }

    /**
     * @param string $prefix
     *
     * @return  string
     */
    public static function getArticleIsPublishedFilters($prefix = 'a')
    {
        $nowDate  = self::getNowDate();
        $nullDate = self::getNullDate();

        $wheres = [];

        $wheres[] = self::is($prefix . '.state', 1);

        $wheres[] = self::combine([
            self::is($prefix . '.publish_up', 'NULL'),
            self::is($prefix . '.publish_up', '<=' . $nowDate),
        ], 'OR');

        $wheres[] = self::combine([
            self::is($prefix . '.publish_down', 'NULL'),
            self::is($prefix . '.publish_down', $nullDate),
            self::is($prefix . '.publish_down', '>' . $nowDate),
        ], 'OR');

        return self::combine($wheres, 'AND');
    }

    public static function getIncludesExcludes($values, $remove_exclude_operators = true)
    {
        $includes = [];
        $excludes = [];

        $values = ArrayHelper::toArray($values);

        if (empty($values))
        {
            return [$includes, $excludes];
        }

        foreach ($values as $value)
        {
            if ($value == '')
            {
                $value = '!*';
            }

            if ($value == '!')
            {
                $value = '+';
            }

            if (self::isExclude($value))
            {
                $excludes[] = $remove_exclude_operators
                    ? self::removeOperator($value)
                    : $value;
                continue;
            }

            $includes[] = $value;
        }

        return [$includes, $excludes];
    }

    /**
     * @return  string
     */
    public static function getNowDate()
    {
        return JFactory::getDate()->toSql();
    }

    /**
     * @return  string
     */
    public static function getNullDate()
    {
        return JFactory::getDbo()->getNullDate();
    }

    public static function getOperator($value, $default = '=')
    {
        if (empty($value))
        {
            return $default;
        }

        if (is_array($value))
        {
            $value = array_values($value);

            return self::getOperator(reset($value), $default);
        }

        $regex = '^' . RegEx::quote(self::getOperators(), 'operator');

        if ( ! RegEx::match($regex, $value, $parts))
        {
            return $default;
        }

        $operator = $parts['operator'];

        switch ($operator)
        {
            case '!':
            case '<>':
            case '!NOT!':
                $operator = '!=';
                break;

            case '==':
                $operator = '=';
                break;

            default:
                break;
        }

        return $operator;
    }

    public static function getOperators()
    {
        return ['!NOT!', '!=', '!', '<>', '<=', '<', '>=', '>', '=', '=='];
    }

    /**
     * @return  JDatabaseQuery
     */
    public static function getQuery()
    {
        return JFactory::getDbo()->getQuery(true);
    }

    public static function getQueryComment($class_prefix = '', $caller_offset = 0)
    {
        $callers = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, $caller_offset + 5);

        for ($i = 1; $i <= ($caller_offset + 2); $i++)
        {
            array_shift($callers);
        }

        $callers = array_reverse($callers);

        $lines = [
            JUri::getInstance()->toString(),
        ];

        foreach ($callers as $caller)
        {
            $lines[] = '[' . str_pad($caller['line'] ?? '', 3, ' ', STR_PAD_LEFT) . '] '
                . str_replace(
                    '\\',
                    '.',
                    trim(substr($caller['class'] ?? '', strlen($class_prefix)), '\\')
                )
                . '.' . $caller['function'];
        }

        return implode("\n", $lines);
    }

    /**
     * @param string  $table    The name of the database table.
     * @param boolean $typeOnly True (default) to only return field types.
     *
     * @return  array
     */
    public static function getTableColumns($table, $typeOnly = true)
    {
        $cache = new Cache;

        if ($cache->exists())
        {
            return $cache->get();
        }

        return $cache->set(JFactory::getDbo()->getTableColumns($table, $typeOnly));
    }

    /**
     * Create an IN statement
     * Reverts to a simple equals statement if array just has 1 value
     *
     * @param string|array $keys
     * @param string|array $values
     * @param array|object $options
     *
     * @return string
     */
    public static function in($keys, $values, $options = [])
    {
        $options = (object) ArrayHelper::toArray($options);
        $glue    = $options->glue ?? 'OR';

        if (is_array($keys))
        {
            $wheres = [];

            foreach ($keys as $single_key)
            {
                $wheres[] = self::in($single_key, $values, $options);
            }

            return self::combine($wheres, $glue);
        }

        if (empty($values) && ! is_array($values))
        {
            return $keys . ' = 0';
        }

        $operator = self::getOperator($values);

        if ( ! is_array($values) || count($values) == 1)
        {
            $values = self::removeOperator($values);
            $value  = is_array($values) ? reset($values) : $values;
            $value  = self::prepareValue($value, $options);

            if ($value === 'NULL')
            {
                $operator = $operator == '!=' ? 'IS NOT' : 'IS';
            }

            return $keys . ' ' . $operator . ' ' . $value;
        }

        $values   = ArrayHelper::clean($values);
        $operator = $operator == '!=' ? 'NOT IN' : 'IN';

        if ($glue == 'OR')
        {
            $values = self::removeOperator($values);
            $values = self::prepareValue($values, $options);

            return $keys . ' ' . $operator . ' (' . implode(',', $values) . ')';
        }

        $wheres = [];

        foreach ($values as $value)
        {
            $wheres[] = self::in($keys, $value, $options);
        }

        return self::combine($wheres, $glue);
    }

    /**
     * Creates a WHERE string that handles strings and arrays and deals with wildcards (=> LIKE)
     *
     * @param string|array $keys
     * @param string|array $values
     * @param array|object $options
     *
     * @return string
     */
    public static function is($keys, $values, $options = [])
    {
        $options = (object) ArrayHelper::toArray($options);

        $glue             = $options->glue ?? 'OR';
        $handle_wildcards = $options->handle_wildcards ?? true;

        if (is_array($keys) && $glue == 'OR')
        {
            $wheres = [];

            foreach ($keys as $single_key)
            {
                $wheres[] = self::is($single_key, $values, $options);
            }

            return self::combine($wheres, $glue);
        }

        if (is_array($keys) && $glue == 'AND')
        {
            $options->glue = 'OR';
            $wheres        = [];

            foreach ($values as $single_values)
            {
                $wheres[] = self::is($keys, $single_values, $options);
            }

            return self::combine($wheres, $glue);
        }

        $db_key = self::quoteName($keys);

        if ( ! is_array($values)
            && $handle_wildcards
            && strpos($values, '*') !== false
        )
        {
            return self::like($db_key, $values, $options);
        }

        if ( ! is_array($values))
        {
            return self::in($db_key, $values, $options);
        }

        $includes = [];
        $excludes = [];
        $wheres   = [];

        foreach ($values as $value)
        {
            if ($handle_wildcards && strpos($value, '*') !== false)
            {
                $wheres[] = self::is($keys, $value, $options);
                continue;
            }

            if (self::isExclude($value))
            {
                $excludes[] = $value;
                continue;
            }

            $includes[] = $value;
        }

        if ( ! empty($includes))
        {
            $wheres[] = self::in($db_key, $includes, $options);
        }

        if ( ! empty($excludes))
        {
            $wheres[] = self::in($db_key, $excludes, $options);
        }

        if (empty($wheres))
        {
            return '0';
        }

        if (count($wheres) == 1)
        {
            return reset($wheres);
        }

        return self::combine($wheres, $glue);
    }

    public static function isExclude($string)
    {
        return in_array(self::getOperator($string), ['!=', '<>'], true);
    }

    /**
     * Creates a WHERE string that handles strings and arrays and deals with wildcards (=> LIKE)
     *
     * @param string|array $key
     * @param string|array $value
     * @param array|object $options
     *
     * @return string
     */
    public static function isNot($key, $value, $options = [])
    {
        if (is_array($key))
        {
            $wheres = [];

            foreach ($key as $single_key)
            {
                $wheres[] = self::isNot($single_key, $value, $options);
            }

            return self::combine($wheres, 'AND');
        }

        $values = $value;

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

        foreach ($values as $i => $value)
        {
            $operator = self::isExclude($value) ? '=' : '!=';

            $values[$i] = $operator . self::removeOperator($value);
        }

        return self::is($key, $values, $options);
    }

    /**
     * Create an LIKE statement
     *
     * @param string       $key
     * @param string|array $value
     * @param array|object $options
     *
     * @return string
     */
    public static function like($key, $value, $options = [])
    {
        $array = ArrayHelper::applyMethodToValues([$key, $value, $options], '', '', 1);

        if ( ! is_null($array))
        {
            return $array;
        }

        $options = (object) ArrayHelper::toArray($options);

        $key = 'LOWER(' . $key . ')';

        $operator = self::getOperator($value);
        $operator = $operator == '!=' ? 'NOT LIKE' : 'LIKE';

        $value = self::removeOperator($value);
        $value = self::prepareValue($value, $options);
        $value = str_replace(['*', '_'], ['%', '\\_'], $value);

        if (strpos($value, '%') === false)
        {
            $value = 'LOWER(' . $value . ')';
        }

        return $key . ' ' . $operator . ' ' . $value;
    }

    /**
     * Create an NOT IN statement
     * Reverts to a simple equals statement if array just has 1 value
     *
     * @param string|array $keys
     * @param string|array $values
     * @param array|object $options
     *
     * @return string
     */
    public static function notIn($keys, $values, $options = [])
    {
        if (is_array($values) && count($values) > 0)
        {
            $values[0] = '!' . $values[0];
        }

        return self::in($keys, $values, $options);
    }

    public static function prepareValue($value, $options = [])
    {
        $array = ArrayHelper::applyMethodToValues([$value, $options]);

        if ( ! is_null($array))
        {
            return $array;
        }

        if ( ! is_array($value) && $value === 'NULL')
        {
            return $value;
        }

        $options = (object) ArrayHelper::toArray($options);

        $handle_now = $options->handle_now ?? true;

        $dates = ['now', 'now()', 'date()', 'jfactory::getdate()'];

        if ($handle_now && ! is_array($value) && in_array(strtolower($value), $dates, true))
        {
            return 'NOW()';
        }

        if (
            (empty($options->quote) || ! $options->quote)
            && (is_int($value) || ctype_digit($value))
        )
        {
            return $value;
        }

        $value = self::quote($value);

        return $value;
    }

    /**
     * @param array|string $text
     * @param boolean      $escape
     *
     * @return  string  The quoted input string.
     */
    public static function quote($text, $escape = true)
    {
        $array = ArrayHelper::applyMethodToValues([$text, $escape]);

        if ( ! is_null($array))
        {
            return $array;
        }

        if (is_null($text))
        {
            return 'NULL';
        }

        return JFactory::getDbo()->quote($text, $escape);
    }

    /**
     * @param array|string $name
     * @param array|string $as
     *
     * @return  array|string
     */
    public static function quoteName($name, $as = null)
    {
        return JFactory::getDbo()->quoteName($name, $as);
    }

    public static function removeOperator($string)
    {
        $array = ArrayHelper::applyMethodToValues([$string]);

        if ( ! is_null($array))
        {
            return $array;
        }

        $regex = '^' . RegEx::quote(self::getOperators(), 'operator');

        return RegEx::replace($regex, '', $string);
    }

    /**
     * Check if a table exists in the database
     *
     * @param string $table
     *
     * @return bool
     */
    public static function tableExists($table)
    {
        if (isset(self::$tables[$table]))
        {
            return self::$tables[$table];
        }

        $db = JFactory::getDbo();

        if (strpos($table, '#__') === 0)
        {
            $table = $db->getPrefix() . substr($table, 3);
        }

        if (strpos($table, $db->getPrefix()) !== 0)
        {
            $table = $db->getPrefix() . $table;
        }

        $query = 'SHOW TABLES LIKE ' . $db->quote($table);
        $db->setQuery($query);
        $result = $db->loadResult();

        self::$tables[$table] = ! empty($result);

        return self::$tables[$table];
    }
}
Site is undergoing maintenance

PACJA Events

Maintenance mode is on

Site will be available soon. Thank you for your patience!