Your IP : 216.73.216.224


Current Path : /var/www/html/administrator/components/com_osmembership/libraries/mpf/model/
Upload File :
Current File : /var/www/html/administrator/components/com_osmembership/libraries/mpf/model/list.php

<?php
/**
 * @package     MPF
 * @subpackage  Model
 *
 * @copyright   Copyright (C) 2016 Ossolution Team, Inc. All rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE
 */

defined('_JEXEC') or die;

use Joomla\CMS\Factory;
use Joomla\CMS\Pagination\Pagination;
use Joomla\Database\DatabaseQuery;
use Joomla\Database\ParameterType;

/**
 * Model class for handling lists of items.
 *
 * @package     MPF
 * @subpackage  Model
 * @since       2.0
 */
class MPFModelList extends MPFModel
{
	/**
	 * The query object of the model
	 *
	 * @var \Joomla\Database\DatabaseQuery
	 */
	protected $query;
	/**
	 * List total
	 *
	 * @var int
	 */
	protected $total;

	/**
	 * Model list data
	 *
	 * @var array
	 */
	protected $data;

	/**
	 * Pagination object
	 *
	 * @var \Joomla\CMS\Pagination\Pagination
	 */
	protected $pagination;

	/**
	 * Name of state field name, usually be tbl.state or tbl.published
	 *
	 * @var string
	 */
	protected $stateField;

	/**
	 * List of fields which will be used for searching data from database table
	 *
	 * @var array
	 */
	protected $searchFields = [];

	/**
	 * Remember model states, always set to true for model list
	 * @var bool
	 */
	public $rememberStates = true;

	/**
	 * Clear join clause for getTotal method
	 *
	 * @var bool
	 */
	protected $clearJoin = true;

	/**
	 * List of states which are excluded from isFiltersActive check
	 *
	 * @var string[]
	 */
	protected $excludeStatesFromActiveFiltersCheck = [
		'filter_order',
		'filter_order_Dir',
		'filter_search',
		'filter_full_ordering',
	];

	/**
	 * List of none standard filters which will be included in isFiltersActive check
	 *
	 * @var array
	 */
	protected $includeStatesFromActiveFiltersCheck = [];

	/**
	 * Instantiate the model.
	 *
	 * @param   array  $config  configuration data for the model
	 */
	public function __construct($config = [])
	{
		parent::__construct($config);

		$this->query = $this->db->getQuery(true);

		$fields = array_keys($this->db->getTableColumns($this->table));

		if (in_array('ordering', $fields))
		{
			$defaultOrdering = 'tbl.ordering';
		}
		else
		{
			$defaultOrdering = 'tbl.id';
		}

		if (in_array('published', $fields))
		{
			$this->stateField = 'tbl.published';
		}
		else
		{
			$this->stateField = 'tbl.state';
		}

		$listLimit = Factory::getApplication()->get('list_limit');

		if ($listLimit > 500)
		{
			$listLimit = 500;
		}

		$this->state->insert('limit', 'int', $listLimit)
			->insert('limitstart', 'int', 0)
			->insert('filter_order', 'cmd', $defaultOrdering)
			->insert('filter_order_Dir', 'word', 'asc')
			->insert('filter_search', 'string', '')
			->insert('filter_state', 'string')
			->insert('filter_access', 'int', 0)
			->insert('filter_language', 'string')
			->insert('filter_full_ordering', 'string');

		if (isset($config['search_fields']))
		{
			$this->searchFields = (array) $config['search_fields'];
		}
		else
		{
			// Build the search field array automatically, basically, we should search based on name, title, description if these fields are available
			if (in_array('name', $fields))
			{
				$this->searchFields[] = 'tbl.name';
			}

			if (in_array('title', $fields))
			{
				$this->searchFields[] = 'tbl.title';
			}

			if (in_array('alias', $fields))
			{
				$this->searchFields[] = 'tbl.alias';
			}
		}

		if (isset($config['clear_join']))
		{
			$this->clearJoin = $config['clear_join'];
		}
	}

	/**
	 * Get a list of items
	 *
	 * @param   bool  $returnIterator
	 *
	 * @return array
	 */
	public function getData($returnIterator = false)
	{
		if (empty($this->data))
		{
			$db = $this->getDbo();

			$query = $this->buildListQuery();

			$this->beforeQueryData($query);

			// Adjust the limitStart state property
			$limit = $this->state->limit;

			if ($limit)
			{
				$offset = $this->state->limitstart;
				$total  = $this->getTotal();

				//If the offset is higher than the total recalculate the offset
				if ($offset !== 0 && $total !== 0 && $offset >= $total)
				{
					$offset                  = floor(($total - 1) / $limit) * $limit;
					$this->state->limitstart = $offset;
				}
			}

			$db->setQuery($query, $this->state->limitstart, $this->state->limit);

			if ($returnIterator)
			{
				$this->data = $db->getIterator();
			}
			else
			{
				$this->data = $db->loadObjectList();
			}

			$this->beforeReturnData($this->data);

			// Store the query so that it can be used in getTotal method if needed
			$this->query = $query;
		}

		return $this->data;
	}

	/**
	 * Get total record. Child class should override this method if needed
	 *
	 * @return int Number of records
	 */
	public function getTotal()
	{
		if (empty($this->total))
		{
			$db    = $this->getDbo();
			$query = $this->buildTotalQuery();
			$this->beforeQueryTotal($query);
			$db->setQuery($query);
			$this->total = (int) $db->loadResult();
		}

		return $this->total;
	}

	/**
	 * Get pagination object
	 *
	 * @return \Joomla\CMS\Pagination\Pagination
	 */
	public function getPagination()
	{
		// Lets load the content if it doesn't already exist
		if (empty($this->pagination))
		{
			$this->pagination = new Pagination($this->getTotal(), $this->state->limitstart, $this->state->limit);
		}

		return $this->pagination;
	}

	/**
	 * Return the query, allow external code a change to manipulate the query when required
	 *
	 * @return \Joomla\Database\DatabaseQuery
	 */
	public function getQuery()
	{
		return $this->query;
	}

	/**
	 * Method to check if filter is active
	 *
	 * @return bool
	 */
	public function isFiltersActive(): bool
	{
		$state = $this->getState();

		foreach ($state->getProperties() as $name)
		{
			/**
			 * Ignore some core states which should not be included in the check
			 */
			if (in_array($name, $this->excludeStatesFromActiveFiltersCheck))
			{
				continue;
			}

			// Only check if state name stars with filter_ or if the state is specified in includeStatesFromActiveFiltersCheck property
			if (!str_contains($name, 'filter_') && !in_array($name, $this->includeStatesFromActiveFiltersCheck))
			{
				continue;
			}

			// If a none default option is selected, the state is active
			if ($state->get($name) != $state->getDefault($name))
			{
				return true;
			}
		}

		return false;
	}

	/**
	 * Build the query object which is used to get list of records from database
	 *
	 * @return \Joomla\Database\DatabaseQuery
	 */
	protected function buildListQuery()
	{
		$query = $this->query;

		$this->buildQueryColumns($query)
			->buildQueryFrom($query)
			->buildQueryJoins($query)
			->buildQueryWhere($query)
			->buildQueryGroup($query)
			->buildQueryHaving($query)
			->buildQueryOrder($query);

		return $query;
	}

	/**
	 * Build query object use to get total records from database
	 *
	 * @return \Joomla\Database\DatabaseQuery
	 */
	protected function buildTotalQuery()
	{
		$query = clone $this->query;

		$query->clear('select')
			->clear('group')
			->clear('having')
			->clear('order')
			->clear('limit')
			->select('COUNT(*)');

		// Clear join clause if needed
		if ($this->clearJoin)
		{
			$query->clear('join');
		}

		return $query;
	}

	/**
	 * Builds SELECT columns list for the query
	 *
	 * @param   \Joomla\Database\DatabaseQuery  $query
	 *
	 * @return $this
	 */
	protected function buildQueryColumns(DatabaseQuery $query)
	{
		$query->select(['tbl.*']);

		return $this;
	}

	/**
	 * Builds FROM tables list for the query
	 *
	 * @param   \Joomla\Database\DatabaseQuery  $query
	 *
	 * @return $this
	 */
	protected function buildQueryFrom(DatabaseQuery $query)
	{
		$query->from($this->table . ' AS tbl');

		return $this;
	}

	/**
	 * Builds JOINS clauses for the query
	 *
	 * @param   \Joomla\Database\DatabaseQuery  $query
	 *
	 * @return $this
	 */
	protected function buildQueryJoins(DatabaseQuery $query)
	{
		return $this;
	}

	/**
	 * Builds a WHERE clause for the query
	 *
	 * @param   \Joomla\Database\DatabaseQuery  $query
	 *
	 * @return $this
	 */
	protected function buildQueryWhere(DatabaseQuery $query)
	{
		$user  = Factory::getApplication()->getIdentity();
		$db    = $this->getDbo();
		$state = $this->state;

		if ($state->filter_state == 'P')
		{
			$query->where($this->stateField . ' = 1');
		}
		elseif ($state->filter_state == 'U')
		{
			$query->where($this->stateField . ' = 0');
		}

		if ($state->filter_access)
		{
			$query->where('tbl.access = ' . (int) $state->filter_access);

			if (!$user->authorise('core.admin'))
			{
				$query->whereIn('tbl.access', $user->getAuthorisedViewLevels());
			}
		}

		$state->filter_search = trim($state->filter_search);

		if ($state->filter_search)
		{
			$this->applySearchFilter($query);
		}

		if ($state->filter_language && $state->filter_language != '*')
		{
			$query->whereIn('tbl.language', [$state->filter_language, '*'], ParameterType::STRING);
		}

		return $this;
	}

	/**
	 * Apply search filter
	 *
	 * @param   \Joomla\Database\DatabaseQuery  $query
	 *
	 * @return $this
	 */
	protected function applySearchFilter(DatabaseQuery $query)
	{
		$db    = $this->getDbo();
		$state = $this->state;

		//Remove blank space from searching
		if (stripos($state->filter_search, 'id:') === 0)
		{
			$query->where('tbl.id = ' . (int) substr($state->filter_search, 3));
		}
		else
		{
			$search = $db->quote('%' . $db->escape($state->filter_search, true) . '%', false);

			if (is_array($this->searchFields))
			{
				$whereOr = [];

				foreach ($this->searchFields as $searchField)
				{
					$whereOr[] = " LOWER($searchField) LIKE " . $search;
				}

				$query->where('(' . implode(' OR ', $whereOr) . ') ');
			}
		}
	}

	/**
	 * Builds a GROUP BY clause for the query
	 *
	 * @param   \Joomla\Database\DatabaseQuery  $query
	 *
	 * @return $this
	 */
	protected function buildQueryGroup(DatabaseQuery $query)
	{
		return $this;
	}

	/**
	 * Builds a HAVING clause for the query
	 *
	 * @param   \Joomla\Database\DatabaseQuery  $query
	 *
	 * @return $this
	 */
	protected function buildQueryHaving(DatabaseQuery $query)
	{
		return $this;
	}

	/**
	 * Builds a generic ORDER BY clasue based on the model's state
	 *
	 * @param   \Joomla\Database\DatabaseQuery  $query
	 *
	 * @return $this
	 */
	protected function buildQueryOrder(DatabaseQuery $query)
	{
		$sort      = $this->state->filter_order;
		$direction = strtoupper($this->state->filter_order_Dir);
		if ($sort)
		{
			$query->order($sort . ' ' . $direction);
		}

		return $this;
	}

	/**
	 * This method give child class a chance to adjust the query before it is run to return list of records
	 *
	 * @param   \Joomla\Database\DatabaseQuery  $query
	 */
	protected function beforeQueryData(DatabaseQuery $query)
	{
	}

	/**
	 * This method give child class a chance to adjust the query object before it is run to return total records
	 *
	 * @param   \Joomla\Database\DatabaseQuery  $query
	 */
	protected function beforeQueryTotal(DatabaseQuery $query)
	{
	}

	/**
	 * This method give child class to adjust the return data in getData method without having to override the
	 * whole method
	 *
	 * @param   array  $rows
	 */
	protected function beforeReturnData($rows)
	{
	}
}