Spade
Mini Shell
| Directory:~$ /home/lmsyaran/public_html/joomla4/ |
| [Home] [System Details] [Kill Me] |
AdminModel.php000064400000035421151155743370007306 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)
{
}
}BaseDatabaseModel.php000064400000033524151155743370010557 0ustar00<?php
/**
* Joomla! Content Management System
*
* @copyright Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
namespace Joomla\CMS\MVC\Model;
defined('JPATH_PLATFORM') or die;
use Joomla\Utilities\ArrayHelper;
/**
* Base class for a database aware Joomla Model
*
* Acts as a Factory class for application specific objects and provides
many supporting API functions.
*
* @since 2.5.5
*/
abstract class BaseDatabaseModel extends \JObject
{
/**
* Indicates if the internal state has been set
*
* @var boolean
* @since 3.0
*/
protected $__state_set = null;
/**
* Database Connector
*
* @var \JDatabaseDriver
* @since 3.0
*/
protected $_db;
/**
* The model (base) name
*
* @var string
* @since 3.0
*/
protected $name;
/**
* The URL option for the component.
*
* @var string
* @since 3.0
*/
protected $option = null;
/**
* A state object
*
* @var \JObject
* @since 3.0
*/
protected $state;
/**
* The event to trigger when cleaning cache.
*
* @var string
* @since 3.0
*/
protected $event_clean_cache = null;
/**
* Add a directory where \JModelLegacy should search for models. You may
* either pass a string or an array of directories.
*
* @param mixed $path A path or array[sting] of paths to search.
* @param string $prefix A prefix for models.
*
* @return array An array with directory elements. If prefix is equal to
'', all directories are returned.
*
* @since 3.0
*/
public static function addIncludePath($path = '', $prefix =
'')
{
static $paths;
if (!isset($paths))
{
$paths = array();
}
if (!isset($paths[$prefix]))
{
$paths[$prefix] = array();
}
if (!isset($paths['']))
{
$paths[''] = array();
}
if (!empty($path))
{
jimport('joomla.filesystem.path');
foreach ((array) $path as $includePath)
{
if (!in_array($includePath, $paths[$prefix]))
{
array_unshift($paths[$prefix], \JPath::clean($includePath));
}
if (!in_array($includePath, $paths['']))
{
array_unshift($paths[''], \JPath::clean($includePath));
}
}
}
return $paths[$prefix];
}
/**
* Adds to the stack of model table paths in LIFO order.
*
* @param mixed $path The directory as a string or directories as an
array to add.
*
* @return void
*
* @since 3.0
*/
public static function addTablePath($path)
{
\JTable::addIncludePath($path);
}
/**
* Create the filename for a resource
*
* @param string $type The resource type to create the filename for.
* @param array $parts An associative array of filename information.
*
* @return string The filename
*
* @since 3.0
*/
protected static function _createFileName($type, $parts = array())
{
$filename = '';
switch ($type)
{
case 'model':
$filename = strtolower($parts['name']) . '.php';
break;
}
return $filename;
}
/**
* Returns a Model object, always creating it
*
* @param string $type The model type to instantiate
* @param string $prefix Prefix for the model class name. Optional.
* @param array $config Configuration array for model. Optional.
*
* @return \JModelLegacy|boolean A \JModelLegacy instance or false on
failure
*
* @since 3.0
*/
public static function getInstance($type, $prefix = '', $config
= array())
{
$type = preg_replace('/[^A-Z0-9_\.-]/i', '', $type);
$modelClass = $prefix . ucfirst($type);
if (!class_exists($modelClass))
{
jimport('joomla.filesystem.path');
$path = \JPath::find(self::addIncludePath(null, $prefix),
self::_createFileName('model', array('name' =>
$type)));
if (!$path)
{
$path = \JPath::find(self::addIncludePath(null, ''),
self::_createFileName('model', array('name' =>
$type)));
}
if (!$path)
{
return false;
}
require_once $path;
if (!class_exists($modelClass))
{
\JLog::add(\JText::sprintf('JLIB_APPLICATION_ERROR_MODELCLASS_NOT_FOUND',
$modelClass), \JLog::WARNING, 'jerror');
return false;
}
}
return new $modelClass($config);
}
/**
* Constructor
*
* @param array $config An array of configuration options (name,
state, dbo, table_path, ignore_request).
*
* @since 3.0
* @throws \Exception
*/
public function __construct($config = array())
{
// Guess the option from the class name (Option)Model(View).
if (empty($this->option))
{
$r = null;
if (!preg_match('/(.*)Model/i', get_class($this), $r))
{
throw new
\Exception(\JText::_('JLIB_APPLICATION_ERROR_MODEL_GET_NAME'),
500);
}
$this->option = 'com_' . strtolower($r[1]);
}
// Set the view name
if (empty($this->name))
{
if (array_key_exists('name', $config))
{
$this->name = $config['name'];
}
else
{
$this->name = $this->getName();
}
}
// Set the model state
if (array_key_exists('state', $config))
{
$this->state = $config['state'];
}
else
{
$this->state = new \JObject;
}
// Set the model dbo
if (array_key_exists('dbo', $config))
{
$this->_db = $config['dbo'];
}
else
{
$this->_db = \JFactory::getDbo();
}
// Set the default view search path
if (array_key_exists('table_path', $config))
{
$this->addTablePath($config['table_path']);
}
// @codeCoverageIgnoreStart
elseif (defined('JPATH_COMPONENT_ADMINISTRATOR'))
{
$this->addTablePath(JPATH_COMPONENT_ADMINISTRATOR .
'/tables');
$this->addTablePath(JPATH_COMPONENT_ADMINISTRATOR .
'/table');
}
// @codeCoverageIgnoreEnd
// Set the internal state marker - used to ignore setting state from the
request
if (!empty($config['ignore_request']))
{
$this->__state_set = true;
}
// Set the clean cache event
if (isset($config['event_clean_cache']))
{
$this->event_clean_cache = $config['event_clean_cache'];
}
elseif (empty($this->event_clean_cache))
{
$this->event_clean_cache = 'onContentCleanCache';
}
}
/**
* Gets an array of objects from the results of database query.
*
* @param string $query The query.
* @param integer $limitstart Offset.
* @param integer $limit The number of records.
*
* @return object[] An array of results.
*
* @since 3.0
* @throws \RuntimeException
*/
protected function _getList($query, $limitstart = 0, $limit = 0)
{
$this->getDbo()->setQuery($query, $limitstart, $limit);
return $this->getDbo()->loadObjectList();
}
/**
* Returns a record count for the query.
*
* Note: Current implementation of this method assumes that getListQuery()
returns a set of unique rows,
* thus it uses SELECT COUNT(*) to count the rows. In cases that
getListQuery() uses DISTINCT
* then either this method must be overridden by a custom implementation
at the derived Model Class
* or a GROUP BY clause should be used to make the set unique.
*
* @param \JDatabaseQuery|string $query The query.
*
* @return integer Number of rows for query.
*
* @since 3.0
*/
protected function _getListCount($query)
{
// Use fast COUNT(*) on \JDatabaseQuery objects if there is no GROUP BY
or HAVING clause:
if ($query instanceof \JDatabaseQuery
&& $query->type == 'select'
&& $query->group === null
&& $query->union === null
&& $query->unionAll === null
&& $query->having === null)
{
$query = clone $query;
$query->clear('select')->clear('order')->clear('limit')->clear('offset')->select('COUNT(*)');
$this->getDbo()->setQuery($query);
return (int) $this->getDbo()->loadResult();
}
// Otherwise fall back to inefficient way of counting all results.
// Remove the limit and offset part if it's a \JDatabaseQuery object
if ($query instanceof \JDatabaseQuery)
{
$query = clone $query;
$query->clear('limit')->clear('offset');
}
$this->getDbo()->setQuery($query);
$this->getDbo()->execute();
return (int) $this->getDbo()->getNumRows();
}
/**
* Method to load and return a model object.
*
* @param string $name The name of the view
* @param string $prefix The class prefix. Optional.
* @param array $config Configuration settings to pass to
\JTable::getInstance
*
* @return \JTable|boolean Table object or boolean false if failed
*
* @since 3.0
* @see \JTable::getInstance()
*/
protected function _createTable($name, $prefix = 'Table',
$config = array())
{
// Clean the model name
$name = preg_replace('/[^A-Z0-9_]/i', '', $name);
$prefix = preg_replace('/[^A-Z0-9_]/i', '', $prefix);
// Make sure we are returning a DBO object
if (!array_key_exists('dbo', $config))
{
$config['dbo'] = $this->getDbo();
}
return \JTable::getInstance($name, $prefix, $config);
}
/**
* Method to get the database driver object
*
* @return \JDatabaseDriver
*
* @since 3.0
*/
public function getDbo()
{
return $this->_db;
}
/**
* Method to get the model name
*
* The model name. By default parsed using the classname or it can be set
* by passing a $config['name'] in the class constructor
*
* @return string The name of the model
*
* @since 3.0
* @throws \Exception
*/
public function getName()
{
if (empty($this->name))
{
$r = null;
if (!preg_match('/Model(.*)/i', get_class($this), $r))
{
throw new
\Exception(\JText::_('JLIB_APPLICATION_ERROR_MODEL_GET_NAME'),
500);
}
$this->name = strtolower($r[1]);
}
return $this->name;
}
/**
* Method to get model state variables
*
* @param string $property Optional parameter name
* @param mixed $default Optional default value
*
* @return mixed The property where specified, the state object where
omitted
*
* @since 3.0
*/
public function getState($property = null, $default = null)
{
if (!$this->__state_set)
{
// Protected method to auto-populate the model state.
$this->populateState();
// Set the model state set flag to true.
$this->__state_set = true;
}
return $property === null ? $this->state :
$this->state->get($property, $default);
}
/**
* Method to get a table object, load it if necessary.
*
* @param string $name The table name. Optional.
* @param string $prefix The class prefix. Optional.
* @param array $options Configuration array for model. Optional.
*
* @return \JTable A \JTable object
*
* @since 3.0
* @throws \Exception
*/
public function getTable($name = '', $prefix =
'Table', $options = array())
{
if (empty($name))
{
$name = $this->getName();
}
if ($table = $this->_createTable($name, $prefix, $options))
{
return $table;
}
throw new
\Exception(\JText::sprintf('JLIB_APPLICATION_ERROR_TABLE_NAME_NOT_SUPPORTED',
$name), 0);
}
/**
* Method to load a row for editing from the version history table.
*
* @param integer $versionId Key to the version history table.
* @param \JTable &$table Content table object being loaded.
*
* @return boolean False on failure or error, true otherwise.
*
* @since 3.2
*/
public function loadHistory($versionId, \JTable &$table)
{
// Only attempt to check the row in if it exists, otherwise do an early
exit.
if (!$versionId)
{
return false;
}
// Get an instance of the row to checkout.
$historyTable = \JTable::getInstance('Contenthistory');
if (!$historyTable->load($versionId))
{
$this->setError($historyTable->getError());
return false;
}
$rowArray =
ArrayHelper::fromObject(json_decode($historyTable->version_data));
$typeId =
\JTable::getInstance('Contenttype')->getTypeId($this->typeAlias);
if ($historyTable->ucm_type_id != $typeId)
{
$this->setError(\JText::_('JLIB_APPLICATION_ERROR_HISTORY_ID_MISMATCH'));
$key = $table->getKeyName();
if (isset($rowArray[$key]))
{
$table->checkIn($rowArray[$key]);
}
return false;
}
$this->setState('save_date', $historyTable->save_date);
$this->setState('version_note',
$historyTable->version_note);
return $table->bind($rowArray);
}
/**
* Method to auto-populate the model state.
*
* This method should only be called once per instantiation and is
designed
* to be called on the first call to the getState() method unless the
model
* configuration flag to ignore the request is set.
*
* @return void
*
* @note Calling getState in this method will result in recursion.
* @since 3.0
*/
protected function populateState()
{
}
/**
* Method to set the database driver object
*
* @param \JDatabaseDriver $db A \JDatabaseDriver based object
*
* @return void
*
* @since 3.0
*/
public function setDbo($db)
{
$this->_db = $db;
}
/**
* Method to set model state variables
*
* @param string $property The name of the property.
* @param mixed $value The value of the property to set or null.
*
* @return mixed The previous value of the property or null if not set.
*
* @since 3.0
*/
public function setState($property, $value = null)
{
return $this->state->set($property, $value);
}
/**
* Clean the cache
*
* @param string $group The cache group
* @param integer $clientId The ID of the client
*
* @return void
*
* @since 3.0
*/
protected function cleanCache($group = null, $clientId = 0)
{
$conf = \JFactory::getConfig();
$options = array(
'defaultgroup' => $group ?: (isset($this->option) ?
$this->option :
\JFactory::getApplication()->input->get('option')),
'cachebase' => $clientId ? JPATH_ADMINISTRATOR .
'/cache' : $conf->get('cache_path', JPATH_SITE .
'/cache'),
'result' => true,
);
try
{
/** @var \JCacheControllerCallback $cache */
$cache = \JCache::getInstance('callback', $options);
$cache->clean();
}
catch (\JCacheException $exception)
{
$options['result'] = false;
}
// Trigger the onContentCleanCache event.
\JEventDispatcher::getInstance()->trigger($this->event_clean_cache,
$options);
}
}
FormModel.php000064400000023107151155743370007157 0ustar00<?php
/**
* Joomla! Content Management System
*
* @copyright Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
namespace Joomla\CMS\MVC\Model;
defined('JPATH_PLATFORM') or die;
use Joomla\Utilities\ArrayHelper;
/**
* Prototype form model.
*
* @see \JForm
* @see \JFormField
* @see \JFormRule
* @since 1.6
*/
abstract class FormModel extends BaseDatabaseModel
{
/**
* Array of form objects.
*
* @var \JForm[]
* @since 1.6
*/
protected $_forms = array();
/**
* Maps events to plugin groups.
*
* @var array
* @since 3.6
*/
protected $events_map = null;
/**
* Constructor.
*
* @param array $config An optional associative array of configuration
settings.
*
* @see \JModelLegacy
* @since 3.6
*/
public function __construct($config = array())
{
$config['events_map'] = isset($config['events_map'])
? $config['events_map'] : array();
$this->events_map = array_merge(
array(
'validate' => 'content',
),
$config['events_map']
);
parent::__construct($config);
}
/**
* Method to checkin a row.
*
* @param integer $pk The numeric id of the primary key.
*
* @return boolean False on failure or error, true otherwise.
*
* @since 1.6
*/
public function checkin($pk = null)
{
// Only attempt to check the row in if it exists.
if ($pk)
{
$user = \JFactory::getUser();
// Get an instance of the row to checkin.
$table = $this->getTable();
if (!$table->load($pk))
{
$this->setError($table->getError());
return false;
}
$checkedOutField = $table->getColumnAlias('checked_out');
$checkedOutTimeField =
$table->getColumnAlias('checked_out_time');
// If there is no checked_out or checked_out_time field, just return
true.
if (!property_exists($table, $checkedOutField) ||
!property_exists($table, $checkedOutTimeField))
{
return true;
}
// Check if this is the user having previously checked out the row.
if ($table->{$checkedOutField} > 0 &&
$table->{$checkedOutField} != $user->get('id') &&
!$user->authorise('core.manage', 'com_checkin'))
{
$this->setError(\JText::_('JLIB_APPLICATION_ERROR_CHECKIN_USER_MISMATCH'));
return false;
}
// Attempt to check the row in.
if (!$table->checkIn($pk))
{
$this->setError($table->getError());
return false;
}
}
return true;
}
/**
* Method to check-out a row for editing.
*
* @param integer $pk The numeric id of the primary key.
*
* @return boolean False on failure or error, true otherwise.
*
* @since 1.6
*/
public function checkout($pk = null)
{
// Only attempt to check the row in if it exists.
if ($pk)
{
// Get an instance of the row to checkout.
$table = $this->getTable();
if (!$table->load($pk))
{
$this->setError($table->getError());
return false;
}
$checkedOutField = $table->getColumnAlias('checked_out');
$checkedOutTimeField =
$table->getColumnAlias('checked_out_time');
// If there is no checked_out or checked_out_time field, just return
true.
if (!property_exists($table, $checkedOutField) ||
!property_exists($table, $checkedOutTimeField))
{
return true;
}
$user = \JFactory::getUser();
// Check if this is the user having previously checked out the row.
if ($table->{$checkedOutField} > 0 &&
$table->{$checkedOutField} != $user->get('id'))
{
$this->setError(\JText::_('JLIB_APPLICATION_ERROR_CHECKOUT_USER_MISMATCH'));
return false;
}
// Attempt to check the row out.
if (!$table->checkOut($user->get('id'), $pk))
{
$this->setError($table->getError());
return false;
}
}
return true;
}
/**
* Abstract method for getting the form from the model.
*
* @param array $data Data for the form.
* @param boolean $loadData True if the form is to load its own data
(default case), false if not.
*
* @return \JForm|boolean A \JForm object on success, false on failure
*
* @since 1.6
*/
abstract public function getForm($data = array(), $loadData = true);
/**
* Method to get a form object.
*
* @param string $name The name of the form.
* @param string $source The form source. Can be XML string if file
flag is set to false.
* @param array $options Optional array of options for the form
creation.
* @param boolean $clear Optional argument to force load a new form.
* @param string $xpath An optional xpath to search for the fields.
*
* @return \JForm|boolean \JForm object on success, false on error.
*
* @see \JForm
* @since 1.6
*/
protected function loadForm($name, $source = null, $options = array(),
$clear = false, $xpath = false)
{
// Handle the optional arguments.
$options['control'] = ArrayHelper::getValue((array) $options,
'control', false);
// Create a signature hash. But make sure, that loading the data does not
create a new instance
$sigoptions = $options;
if (isset($sigoptions['load_data']))
{
unset($sigoptions['load_data']);
}
$hash = md5($source . serialize($sigoptions));
// Check if we can use a previously loaded form.
if (!$clear && isset($this->_forms[$hash]))
{
return $this->_forms[$hash];
}
// Get the form.
\JForm::addFormPath(JPATH_COMPONENT . '/models/forms');
\JForm::addFieldPath(JPATH_COMPONENT . '/models/fields');
\JForm::addFormPath(JPATH_COMPONENT . '/model/form');
\JForm::addFieldPath(JPATH_COMPONENT . '/model/field');
try
{
$form = \JForm::getInstance($name, $source, $options, false, $xpath);
if (isset($options['load_data']) &&
$options['load_data'])
{
// Get the data for the form.
$data = $this->loadFormData();
}
else
{
$data = array();
}
// Allow for additional modification of the form, and events to be
triggered.
// We pass the data because plugins may require it.
$this->preprocessForm($form, $data);
// Load the data into the form after the plugins have operated.
$form->bind($data);
}
catch (\Exception $e)
{
$this->setError($e->getMessage());
return false;
}
// Store the form for later.
$this->_forms[$hash] = $form;
return $form;
}
/**
* Method to get the data that should be injected in the form.
*
* @return array The default data is an empty array.
*
* @since 1.6
*/
protected function loadFormData()
{
return array();
}
/**
* Method to allow derived classes to preprocess the data.
*
* @param string $context The context identifier.
* @param mixed &$data The data to be processed. It gets
altered directly.
* @param string $group The name of the plugin group to import
(defaults to "content").
*
* @return void
*
* @since 3.1
*/
protected function preprocessData($context, &$data, $group =
'content')
{
// Get the dispatcher and load the users plugins.
$dispatcher = \JEventDispatcher::getInstance();
\JPluginHelper::importPlugin($group);
// Trigger the data preparation event.
$results = $dispatcher->trigger('onContentPrepareData',
array($context, &$data));
// Check for errors encountered while preparing the data.
if (count($results) > 0 && in_array(false, $results, true))
{
$this->setError($dispatcher->getError());
}
}
/**
* Method to allow derived classes to preprocess the form.
*
* @param \JForm $form A \JForm object.
* @param mixed $data The data expected for the form.
* @param string $group The name of the plugin group to import
(defaults to "content").
*
* @return void
*
* @see \JFormField
* @since 1.6
* @throws \Exception if there is an error in the form event.
*/
protected function preprocessForm(\JForm $form, $data, $group =
'content')
{
// Import the appropriate plugin group.
\JPluginHelper::importPlugin($group);
// Get the dispatcher.
$dispatcher = \JEventDispatcher::getInstance();
// Trigger the form preparation event.
$results = $dispatcher->trigger('onContentPrepareForm',
array($form, $data));
// Check for errors encountered while preparing the form.
if (count($results) && in_array(false, $results, true))
{
// Get the last error.
$error = $dispatcher->getError();
if (!($error instanceof \Exception))
{
throw new \Exception($error);
}
}
}
/**
* Method to validate the form data.
*
* @param \JForm $form The form to validate against.
* @param array $data The data to validate.
* @param string $group The name of the field group to validate.
*
* @return array|boolean Array of filtered data if valid, false
otherwise.
*
* @see \JFormRule
* @see \JFilterInput
* @since 1.6
*/
public function validate($form, $data, $group = null)
{
// Include the plugins for the delete events.
\JPluginHelper::importPlugin($this->events_map['validate']);
$dispatcher = \JEventDispatcher::getInstance();
$dispatcher->trigger('onUserBeforeDataValidation',
array($form, &$data));
// Filter and validate the form data.
$data = $form->filter($data);
$return = $form->validate($data, $group);
// Check for an error.
if ($return instanceof \Exception)
{
$this->setError($return->getMessage());
return false;
}
// Check the validation results.
if ($return === false)
{
// Get the validation messages from the form.
foreach ($form->getErrors() as $message)
{
$this->setError($message);
}
return false;
}
// Tags B/C break at 3.1.2
if (!isset($data['tags']) &&
isset($data['metadata']['tags']))
{
$data['tags'] = $data['metadata']['tags'];
}
return $data;
}
}
ItemModel.php000064400000002035151155743370007147 0ustar00<?php
/**
* Joomla! Content Management System
*
* @copyright Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
namespace Joomla\CMS\MVC\Model;
defined('JPATH_PLATFORM') or die;
/**
* Prototype item model.
*
* @since 1.6
*/
abstract class ItemModel extends BaseDatabaseModel
{
/**
* An item.
*
* @var array
* @since 1.6
*/
protected $_item = null;
/**
* Model context string.
*
* @var string
* @since 1.6
*/
protected $_context = 'group.type';
/**
* Method to get a store id based on model configuration state.
*
* This is necessary because the model is used by the component and
* different modules that might need different sets of data or different
* ordering requirements.
*
* @param string $id A prefix for the store id.
*
* @return string A store id.
*
* @since 1.6
*/
protected function getStoreId($id = '')
{
// Compile the store id.
return md5($id);
}
}
ListModel.php000064400000022613151155743370007170 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.php000064400000017257151156057320006336 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.php000064400000013446151156057320006352 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;
}
}
}AbstractModel.php000064400000000613151160003150007771 0ustar00<?php
namespace Nextend\Framework\Model;
use Nextend\Framework\Pattern\MVCHelperTrait;
abstract class AbstractModel {
use MVCHelperTrait;
/**
* AbstractModel constructor.
*
* @param MVCHelperTrait $helper
*/
public function __construct($helper) {
$this->setMVCHelper($helper);
$this->init();
}
protected function init() {
}
}AbstractModelTable.php000064400000001047151160003150010743
0ustar00<?php
namespace Nextend\Framework\Model;
use Nextend\Framework\Database\AbstractPlatformConnectorTable;
abstract class AbstractModelTable extends AbstractModel {
/**
* @var AbstractPlatformConnectorTable
*/
protected $table;
protected function init() {
$this->table = $this->createConnectorTable();
}
/**
* @return AbstractPlatformConnectorTable
*/
protected abstract function createConnectorTable();
public function getTableName() {
return $this->table->getTableName();
}
}ApplicationSection.php000064400000004575151160003150011050
0ustar00<?php
namespace Nextend\Framework\Model;
class ApplicationSection {
private $application = 'system';
/**
* Quick cache implementation to prevent duplicate queries. It might
have bugs.
*
* @var array
*/
protected $cache = array();
public function __construct($application) {
$this->application = $application;
}
public function getById($id, $section) {
return Section::getById($id, $section);
}
public function setById($id, $value) {
$this->cache = array();
return Section::setById($id, $value);
}
public function get($section, $referenceKey = null, $default = null) {
if (isset($this->cache[$section . '///' .
$referenceKey])) {
return $this->cache[$section . '///' .
$referenceKey];
}
$attributes = array(
"application" => $this->application,
"section" => $section
);
if ($referenceKey !== null) {
$attributes['referencekey'] = $referenceKey;
}
$result =
Section::$tableSectionStorage->findByAttributes($attributes);
if (is_array($result)) {
$this->cache[$section . '///' . $referenceKey] =
$result['value'];
return $result['value'];
}
return $default;
}
public function getAll($section, $referenceKey = null) {
return Section::getAll($this->application, $section,
$referenceKey);
}
public function set($section, $referenceKey, $value) {
if (isset($this->cache[$section . '///' .
$referenceKey])) {
unset($this->cache[$section . '///' .
$referenceKey]);
}
Section::set($this->application, $section, $referenceKey,
$value);
}
public function add($section, $referenceKey, $value) {
if (isset($this->cache[$section . '///' .
$referenceKey])) {
unset($this->cache[$section . '///' .
$referenceKey]);
}
return Section::add($this->application, $section, $referenceKey,
$value);
}
public function delete($section, $referenceKey = null) {
if (isset($this->cache[$section . '///' .
$referenceKey])) {
unset($this->cache[$section . '///' .
$referenceKey]);
}
return Section::delete($this->application, $section,
$referenceKey);
}
public function deleteById($id) {
return Section::deleteById($id);
}
}Section.php000064400000011165151160003150006655 0ustar00<?php
namespace Nextend\Framework\Model;
use Nextend\Framework\Database\AbstractPlatformConnectorTable;
use Nextend\Framework\Database\Database;
use Nextend\Framework\Plugin;
class Section {
/** @var AbstractPlatformConnectorTable */
public static $tableSectionStorage;
public function __construct() {
self::$tableSectionStorage =
Database::getTable("nextend2_section_storage");
}
public static function get($application, $section, $referenceKey =
null) {
$attributes = array(
"application" => $application,
"section" => $section
);
if ($referenceKey !== null) {
$attributes['referencekey'] = $referenceKey;
}
return
self::$tableSectionStorage->findByAttributes($attributes);
}
public static function getById($id, $section = null) {
static $cache = array();
if ($id === 0) {
return null;
}
if (!isset($cache[$section])) {
$cache[$section] = array();
} else if (isset($cache[$section][$id])) {
return $cache[$section][$id];
}
$cache[$section][$id] = null;
if ($section) {
Plugin::doAction($section, array(
$id,
&$cache[$section][$id]
));
if ($cache[$section][$id]) {
return $cache[$section][$id];
}
}
$cache[$section][$id] =
self::$tableSectionStorage->findByAttributes(array(
"id" => $id
));
if ($section && $cache[$section][$id]['section']
!= $section) {
$cache[$section][$id] = null;
return $cache[$section][$id];
}
return $cache[$section][$id];
}
public static function getAll($application, $section, $referenceKey =
null) {
$attributes = array(
"application" => $application,
"section" => $section
);
if ($referenceKey !== null) {
$attributes['referencekey'] = $referenceKey;
}
$rows =
self::$tableSectionStorage->findAllByAttributes($attributes, array(
"id",
"referencekey",
"value",
"system",
"editable"
));
Plugin::doAction($application . $section, array(
$referenceKey,
&$rows
));
return $rows;
}
public static function add($application, $section, $referenceKey,
$value, $system = 0, $editable = 1) {
$row = array(
"application" => $application,
"section" => $section,
"referencekey" => '',
"value" => $value,
"system" => $system,
"editable" => $editable
);
if ($referenceKey !== null) {
$row["referencekey"] = $referenceKey;
}
self::$tableSectionStorage->insert($row);
return self::$tableSectionStorage->insertId();
}
public static function set($application, $section, $referenceKey,
$value, $system = 0, $editable = 1) {
$result = self::getAll($application, $section, $referenceKey);
if (empty($result)) {
return self::add($application, $section, $referenceKey, $value,
$system, $editable);
} else {
$attributes = array(
"application" => $application,
"section" => $section
);
if ($referenceKey !== null) {
$attributes['referencekey'] = $referenceKey;
}
self::$tableSectionStorage->update(array('value'
=> $value), $attributes);
return true;
}
}
public static function setById($id, $value) {
$result = self::getById($id);
if ($result !== null && $result['editable']) {
self::$tableSectionStorage->update(array('value'
=> $value), array(
"id" => $id
));
return true;
}
return false;
}
public static function delete($application, $section, $referenceKey =
null) {
$attributes = array(
"application" => $application,
"section" => $section,
"system" => 0
);
if ($referenceKey !== null) {
$attributes['referencekey'] = $referenceKey;
}
self::$tableSectionStorage->deleteByAttributes($attributes);
return true;
}
public static function deleteById($id) {
self::$tableSectionStorage->deleteByAttributes(array(
"id" => $id,
"system" => 0
));
return true;
}
}
new Section();StorageSectionManager.php000064400000000722151160003150011472
0ustar00<?php
namespace Nextend\Framework\Model;
class StorageSectionManager {
/** @var ApplicationSection[] */
private static $storageTypes = array();
/**
* @param $type
*
* @return ApplicationSection
*/
public static function getStorage($type) {
if (!isset(self::$storageTypes[$type])) {
self::$storageTypes[$type] = new ApplicationSection($type);
}
return self::$storageTypes[$type];
}
}index.html000064400000000054151160065270006543
0ustar00<html><body
bgcolor="#FFFFFF"></body></html>Load.php000064400000005626151160065270006150
0ustar00<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder
<https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
namespace VDM\Joomla\Model;
use VDM\Joomla\Utilities\StringHelper;
use VDM\Joomla\Utilities\ArrayHelper;
use VDM\Joomla\Utilities\ObjectHelper;
use VDM\Joomla\Interfaces\ModelInterface;
use VDM\Joomla\Abstraction\Model;
/**
* Power Model Load
*
* @since 3.2.2
*/
final class Load extends Model implements ModelInterface
{
/**
* Model the value
* Example: $this->value(value, 'field_key',
'table_name');
*
* @param mixed $value The value to model
* @param string $field The field key
* @param string|null $table The table
*
* @return mixed
* @since 3.2.0
*/
public function value($value, string $field, ?string $table = null)
{
// set the table name
if (empty($table))
{
$table = $this->getTable();
}
// check if this is a valid table (don't touch null)
if ($value !== null && ($store = $this->table->get($table,
$field, 'store')) !== null)
{
// open the value based on the store method
switch($store)
{
case 'base64':
$value = base64_decode((string) $value);
break;
case 'json':
$value = json_decode($value);
break;
}
}
return $value;
}
/**
* Validate before the value is modelled
*
* @param mixed $value The field value
* @param string|null $field The field key
* @param string|null $table The table
*
* @return bool
* @since 3.2.0
*/
protected function validateBefore(&$value, ?string $field = null,
?string $table = null): bool
{
// only strings or numbers allowed
if (StringHelper::check($value) || is_numeric($value))
{
return true;
}
// check if we allow empty
elseif ($this->getAllowEmpty() && empty($value))
{
return true;
}
// remove empty values
return false;
}
/**
* Validate after the value is modelled
*
* @param mixed $value The field value
* @param string|null $field The field key
* @param string|null $table The table
*
* @return bool
* @since 3.2.0
*/
protected function validateAfter(&$value, ?string $field = null,
?string $table = null): bool
{
// only strings or numbers allowed
if (StringHelper::check($value) || ArrayHelper::check($value, true) ||
ObjectHelper::check($value) || is_numeric($value))
{
return true;
}
// check if we allow empty
elseif ($this->getAllowEmpty() && empty($value))
{
return true;
}
// remove empty values
return false;
}
}
Upsert.php000064400000005577151160065270006560 0ustar00<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder
<https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights
reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
namespace VDM\Joomla\Model;
use VDM\Joomla\Utilities\StringHelper;
use VDM\Joomla\Utilities\ArrayHelper;
use VDM\Joomla\Utilities\ObjectHelper;
use VDM\Joomla\Interfaces\ModelInterface;
use VDM\Joomla\Abstraction\Model;
/**
* Power Model Update or Insert
*
* @since 3.2.0
*/
final class Upsert extends Model implements ModelInterface
{
/**
* Model the value
* Example: $this->value(value, 'field_key',
'table_name');
*
* @param mixed $value The value to model
* @param string $field The field key
* @param string|null $table The table
*
* @return mixed
* @since 3.2.0
*/
public function value($value, string $field, ?string $table = null)
{
// set the table name
if (empty($table))
{
$table = $this->getTable();
}
// check if this is a valid table
if (($store = $this->table->get($table, $field, 'store'))
!== null)
{
// open the value based on the store method
switch($store)
{
case 'base64':
$value = base64_encode((string) $value);
break;
case 'json':
$value = json_encode($value, JSON_FORCE_OBJECT);
break;
}
}
return $value;
}
/**
* Validate before the value is modelled
*
* @param mixed $value The field value
* @param string|null $field The field key
* @param string|null $table The table
*
* @return bool
* @since 3.2.0
*/
protected function validateBefore(&$value, ?string $field = null,
?string $table = null): bool
{
// check values
if (StringHelper::check($value) || ArrayHelper::check($value, true) ||
ObjectHelper::check($value) || is_numeric($value))
{
return true;
}
// check if we allow empty
elseif ($this->getAllowEmpty() && empty($value))
{
return true;
}
// remove empty values
return false;
}
/**
* Validate after the value is modelled
*
* @param mixed $value The field value
* @param string|null $field The field key
* @param string|null $table The table
*
* @return bool
* @since 3.2.0
*/
protected function validateAfter(&$value, ?string $field = null,
?string $table = null): bool
{
// only strings or numbers allowed
if (StringHelper::check($value) || is_numeric($value))
{
return true;
}
// check if we allow empty
elseif ($this->getAllowEmpty() && empty($value))
{
return true;
}
// remove empty values
return false;
}
}