Spade
Mini Shell
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;
}
}
}