Spade
Mini Shell
| Directory:~$ /home/lmsyaran/public_html/joomla4/ |
| [Home] [System Details] [Kill Me] |
CallbackController.php000064400000013422151155742510011025 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\Cache\Controller;
defined('JPATH_PLATFORM') or die;
use Joomla\CMS\Cache\Cache;
use Joomla\CMS\Cache\CacheController;
/**
* Joomla! Cache callback type object
*
* @since 1.7.0
*/
class CallbackController extends CacheController
{
/**
* Executes a cacheable callback if not found in cache else returns cached
output and result
*
* Since arguments to this function are read with func_get_args you can
pass any number of arguments to this method
* as long as the first argument passed is the callback definition.
*
* The callback definition can be in several forms:
* - Standard PHP Callback array see <https://www.php.net/callback>
[recommended]
* - Function name as a string eg. 'foo' for function foo()
* - Static method name as a string eg. 'MyClass::myMethod' for
method myMethod() of class MyClass
*
* @return mixed Result of the callback
*
* @since 1.7.0
* @deprecated 4.0
*/
public function call()
{
// Get callback and arguments
$args = func_get_args();
$callback = array_shift($args);
return $this->get($callback, $args);
}
/**
* Executes a cacheable callback if not found in cache else returns cached
output and result
*
* @param mixed $callback Callback or string shorthand for a
callback
* @param array $args Callback arguments
* @param mixed $id Cache ID
* @param boolean $wrkarounds True to use workarounds
* @param array $woptions Workaround options
*
* @return mixed Result of the callback
*
* @since 1.7.0
*/
public function get($callback, $args = array(), $id = false, $wrkarounds =
false, $woptions = array())
{
// Normalize callback
if (is_array($callback) || is_callable($callback))
{
// We have a standard php callback array -- do nothing
}
elseif (strstr($callback, '::'))
{
// This is shorthand for a static method callback classname::methodname
list ($class, $method) = explode('::', $callback);
$callback = array(trim($class), trim($method));
}
elseif (strstr($callback, '->'))
{
/*
* This is a really not so smart way of doing this... we provide this
for backward compatibility but this
* WILL! disappear in a future version. If you are using this syntax
change your code to use the standard
* PHP callback array syntax: <https://www.php.net/callback>
*
* We have to use some silly global notation to pull it off and this is
very unreliable
*/
list ($object_123456789, $method) = explode('->',
$callback);
global $$object_123456789;
$callback = array($$object_123456789, $method);
}
if (!$id)
{
// Generate an ID
$id = $this->_makeId($callback, $args);
}
$data = $this->cache->get($id);
$locktest = (object) array('locked' => null,
'locklooped' => null);
if ($data === false)
{
$locktest = $this->cache->lock($id);
// If locklooped is true try to get the cached data again; it could
exist now.
if ($locktest->locked === true && $locktest->locklooped
=== true)
{
$data = $this->cache->get($id);
}
}
if ($data !== false)
{
if ($locktest->locked === true)
{
$this->cache->unlock($id);
}
$data = unserialize(trim($data));
if ($wrkarounds)
{
echo Cache::getWorkarounds(
$data['output'],
array('mergehead' =>
isset($woptions['mergehead']) ? $woptions['mergehead']
: 0)
);
}
else
{
echo $data['output'];
}
return $data['result'];
}
if (!is_array($args))
{
$referenceArgs = !empty($args) ? array(&$args) : array();
}
else
{
$referenceArgs = &$args;
}
if ($locktest->locked === false && $locktest->locklooped
=== true)
{
// We can not store data because another process is in the middle of
saving
return call_user_func_array($callback, $referenceArgs);
}
$coptions = array();
if (isset($woptions['modulemode']) &&
$woptions['modulemode'] == 1)
{
$document = \JFactory::getDocument();
if (method_exists($document, 'getHeadData'))
{
$coptions['headerbefore'] = $document->getHeadData();
}
$coptions['modulemode'] = 1;
}
else
{
$coptions['modulemode'] = 0;
}
$coptions['nopathway'] =
isset($woptions['nopathway']) ? $woptions['nopathway']
: 1;
$coptions['nohead'] = isset($woptions['nohead'])
? $woptions['nohead'] : 1;
$coptions['nomodules'] =
isset($woptions['nomodules']) ? $woptions['nomodules']
: 1;
ob_start();
ob_implicit_flush(false);
$result = call_user_func_array($callback, $referenceArgs);
$output = ob_get_clean();
$data = array('result' => $result);
if ($wrkarounds)
{
$data['output'] = Cache::setWorkarounds($output, $coptions);
}
else
{
$data['output'] = $output;
}
// Store the cache data
$this->cache->store(serialize($data), $id);
if ($locktest->locked === true)
{
$this->cache->unlock($id);
}
echo $output;
return $result;
}
/**
* Generate a callback cache ID
*
* @param callback $callback Callback to cache
* @param array $args Arguments to the callback method to cache
*
* @return string MD5 Hash
*
* @since 1.7.0
*/
protected function _makeId($callback, $args)
{
if (is_array($callback) && is_object($callback[0]))
{
$vars = get_object_vars($callback[0]);
$vars[] = strtolower(get_class($callback[0]));
$callback[0] = $vars;
}
// A Closure can't be serialized, so to generate the ID we'll
need to get its hash
if (is_a($callback, 'closure'))
{
$hash = spl_object_hash($callback);
return md5($hash . serialize(array($args)));
}
return md5(serialize(array($callback, $args)));
}
}
OutputController.php000064400000010712151155742510010630 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\Cache\Controller;
defined('JPATH_PLATFORM') or die;
use Joomla\CMS\Cache\CacheController;
use Joomla\CMS\Log\Log;
/**
* Joomla Cache output type object
*
* @since 1.7.0
*/
class OutputController extends CacheController
{
/**
* Cache data ID
*
* @var string
* @since 1.7.0
*/
protected $_id;
/**
* Cache data group
*
* @var string
* @since 1.7.0
*/
protected $_group;
/**
* Object to test locked state
*
* @var \stdClass
* @since 1.7.0
* @deprecated 4.0
*/
protected $_locktest = null;
/**
* Start the cache
*
* @param string $id The cache data ID
* @param string $group The cache data group
*
* @return boolean
*
* @since 1.7.0
* @deprecated 4.0
*/
public function start($id, $group = null)
{
Log::add(
__METHOD__ . '() is deprecated.',
Log::WARNING,
'deprecated'
);
// If we have data in cache use that.
$data = $this->cache->get($id, $group);
$this->_locktest = new \stdClass;
$this->_locktest->locked = null;
$this->_locktest->locklooped = null;
if ($data === false)
{
$this->_locktest = $this->cache->lock($id, $group);
if ($this->_locktest->locked == true &&
$this->_locktest->locklooped == true)
{
$data = $this->cache->get($id, $group);
}
}
if ($data !== false)
{
$data = unserialize(trim($data));
echo $data;
if ($this->_locktest->locked == true)
{
$this->cache->unlock($id, $group);
}
return true;
}
// Nothing in cache... let's start the output buffer and start
collecting data for next time.
if ($this->_locktest->locked == false)
{
$this->_locktest = $this->cache->lock($id, $group);
}
ob_start();
ob_implicit_flush(false);
// Set id and group placeholders
$this->_id = $id;
$this->_group = $group;
return false;
}
/**
* Stop the cache buffer and store the cached data
*
* @return boolean True if the cache data was stored
*
* @since 1.7.0
* @deprecated 4.0
*/
public function end()
{
Log::add(
__METHOD__ . '() is deprecated.',
Log::WARNING,
'deprecated'
);
// Get data from output buffer and echo it
$data = ob_get_clean();
echo $data;
// Get the ID and group and reset the placeholders
$id = $this->_id;
$group = $this->_group;
$this->_id = null;
$this->_group = null;
// Get the storage handler and store the cached data
$ret = $this->cache->store(serialize($data), $id, $group);
if ($this->_locktest->locked == true)
{
$this->cache->unlock($id, $group);
}
return $ret;
}
/**
* Get stored cached data by ID and group
*
* @param string $id The cache data ID
* @param string $group The cache data group
*
* @return mixed Boolean false on no result, cached object otherwise
*
* @since 1.7.0
*/
public function get($id, $group = null)
{
$data = $this->cache->get($id, $group);
if ($data === false)
{
$locktest = $this->cache->lock($id, $group);
// If locklooped is true try to get the cached data again; it could
exist now.
if ($locktest->locked === true && $locktest->locklooped
=== true)
{
$data = $this->cache->get($id, $group);
}
if ($locktest->locked === true)
{
$this->cache->unlock($id, $group);
}
}
// Check again because we might get it from second attempt
if ($data !== false)
{
// Trim to fix unserialize errors
$data = unserialize(trim($data));
}
return $data;
}
/**
* Store data to cache by ID and group
*
* @param mixed $data The data to store
* @param string $id The cache data ID
* @param string $group The cache data group
* @param boolean $wrkarounds True to use wrkarounds
*
* @return boolean True if cache stored
*
* @since 1.7.0
*/
public function store($data, $id, $group = null, $wrkarounds = true)
{
$locktest = $this->cache->lock($id, $group);
if ($locktest->locked === false && $locktest->locklooped
=== true)
{
// We can not store data because another process is in the middle of
saving
return false;
}
$result = $this->cache->store(serialize($data), $id, $group);
if ($locktest->locked === true)
{
$this->cache->unlock($id, $group);
}
return $result;
}
}
PageController.php000064400000011104151155742510010200 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\Cache\Controller;
defined('JPATH_PLATFORM') or die;
use Joomla\CMS\Cache\Cache;
use Joomla\CMS\Cache\CacheController;
/**
* Joomla! Cache page type object
*
* @since 1.7.0
*/
class PageController extends CacheController
{
/**
* ID property for the cache page object.
*
* @var integer
* @since 1.7.0
*/
protected $_id;
/**
* Cache group
*
* @var string
* @since 1.7.0
*/
protected $_group;
/**
* Cache lock test
*
* @var \stdClass
* @since 1.7.0
*/
protected $_locktest = null;
/**
* Get the cached page data
*
* @param boolean $id The cache data ID
* @param string $group The cache data group
*
* @return mixed Boolean false on no result, cached object otherwise
*
* @since 1.7.0
*/
public function get($id = false, $group = 'page')
{
// If an id is not given, generate it from the request
if (!$id)
{
$id = $this->_makeId();
}
// If the etag matches the page id ... set a no change header and exit :
utilize browser cache
if (!headers_sent() &&
isset($_SERVER['HTTP_IF_NONE_MATCH']))
{
$etag = stripslashes($_SERVER['HTTP_IF_NONE_MATCH']);
if ($etag == $id)
{
$browserCache = isset($this->options['browsercache']) ?
$this->options['browsercache'] : false;
if ($browserCache)
{
$this->_noChange();
}
}
}
// We got a cache hit... set the etag header and echo the page data
$data = $this->cache->get($id, $group);
$this->_locktest = (object) array('locked' => null,
'locklooped' => null);
if ($data === false)
{
$this->_locktest = $this->cache->lock($id, $group);
// If locklooped is true try to get the cached data again; it could
exist now.
if ($this->_locktest->locked === true &&
$this->_locktest->locklooped === true)
{
$data = $this->cache->get($id, $group);
}
}
if ($data !== false)
{
if ($this->_locktest->locked === true)
{
$this->cache->unlock($id, $group);
}
$data = unserialize(trim($data));
$data = Cache::getWorkarounds($data);
$this->_setEtag($id);
return $data;
}
// Set ID and group placeholders
$this->_id = $id;
$this->_group = $group;
return false;
}
/**
* Stop the cache buffer and store the cached data
*
* @param mixed $data The data to store
* @param string $id The cache data ID
* @param string $group The cache data group
* @param boolean $wrkarounds True to use workarounds
*
* @return boolean
*
* @since 1.7.0
*/
public function store($data, $id, $group = null, $wrkarounds = true)
{
if ($this->_locktest->locked === false &&
$this->_locktest->locklooped === true)
{
// We can not store data because another process is in the middle of
saving
return false;
}
// Get page data from the application object
if (!$data)
{
$data = \JFactory::getApplication()->getBody();
// Only attempt to store if page data exists.
if (!$data)
{
return false;
}
}
// Get id and group and reset the placeholders
if (!$id)
{
$id = $this->_id;
}
if (!$group)
{
$group = $this->_group;
}
if ($wrkarounds)
{
$data = Cache::setWorkarounds(
$data,
array(
'nopathway' => 1,
'nohead' => 1,
'nomodules' => 1,
'headers' => true,
)
);
}
$result = $this->cache->store(serialize($data), $id, $group);
if ($this->_locktest->locked === true)
{
$this->cache->unlock($id, $group);
}
return $result;
}
/**
* Generate a page cache id
*
* @return string MD5 Hash
*
* @since 1.7.0
* @todo Discuss whether this should be coupled to a data hash or a
request hash ... perhaps hashed with a serialized request
*/
protected function _makeId()
{
return Cache::makeId();
}
/**
* There is no change in page data so send an unmodified header and die
gracefully
*
* @return void
*
* @since 1.7.0
*/
protected function _noChange()
{
$app = \JFactory::getApplication();
// Send not modified header and exit gracefully
$app->setHeader('Status', 304, true);
$app->sendHeaders();
$app->close();
}
/**
* Set the ETag header in the response
*
* @param string $etag The entity tag (etag) to set
*
* @return void
*
* @since 1.7.0
*/
protected function _setEtag($etag)
{
\JFactory::getApplication()->setHeader('ETag',
'"' . $etag . '"', true);
}
}
ViewController.php000064400000006431151155742510010245 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\Cache\Controller;
defined('JPATH_PLATFORM') or die;
use Joomla\CMS\Cache\Cache;
use Joomla\CMS\Cache\CacheController;
/**
* Joomla! Cache view type object
*
* @since 1.7.0
*/
class ViewController extends CacheController
{
/**
* Get the cached view data
*
* @param object $view The view object to cache output for
* @param string $method The method name of the view method to
cache output for
* @param mixed $id The cache data ID
* @param boolean $wrkarounds True to enable workarounds.
*
* @return boolean True if the cache is hit (false else)
*
* @since 1.7.0
*/
public function get($view, $method = 'display', $id = false,
$wrkarounds = true)
{
// If an id is not given generate it from the request
if (!$id)
{
$id = $this->_makeId($view, $method);
}
$data = $this->cache->get($id);
$locktest = (object) array('locked' => null,
'locklooped' => null);
if ($data === false)
{
$locktest = $this->cache->lock($id);
/*
* If the loop is completed and returned true it means the lock has been
set.
* If looped is true try to get the cached data again; it could exist
now.
*/
if ($locktest->locked === true && $locktest->locklooped
=== true)
{
$data = $this->cache->get($id);
}
// False means that locking is either turned off or maxtime has been
exceeded. Execute the view.
}
if ($data !== false)
{
if ($locktest->locked === true)
{
$this->cache->unlock($id);
}
$data = unserialize(trim($data));
if ($wrkarounds)
{
echo Cache::getWorkarounds($data);
}
else
{
// No workarounds, so all data is stored in one piece
echo $data;
}
return true;
}
// No hit so we have to execute the view
if (!method_exists($view, $method))
{
return false;
}
if ($locktest->locked === false && $locktest->locklooped
=== true)
{
// We can not store data because another process is in the middle of
saving
$view->$method();
return false;
}
// Capture and echo output
ob_start();
ob_implicit_flush(false);
$view->$method();
$data = ob_get_clean();
echo $data;
/*
* For a view we have a special case. We need to cache not only the
output from the view, but the state
* of the document head after the view has been rendered. This will
allow us to properly cache any attached
* scripts or stylesheets or links or any other modifications that the
view has made to the document object
*/
if ($wrkarounds)
{
$data = Cache::setWorkarounds($data);
}
// Store the cache data
$this->cache->store(serialize($data), $id);
if ($locktest->locked === true)
{
$this->cache->unlock($id);
}
return false;
}
/**
* Generate a view cache ID.
*
* @param object $view The view object to cache output for
* @param string $method The method name to cache for the view object
*
* @return string MD5 Hash
*
* @since 1.7.0
*/
protected function _makeId($view, $method)
{
return md5(serialize(array(Cache::makeId(), get_class($view), $method)));
}
}
AdminController.php000064400000024507151156604430010366 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\Controller;
use OSL\Container\Container;
use Joomla\Utilities\ArrayHelper, JText, JRoute;
defined('_JEXEC') or die;
/**
* Class AdminController
*
* Base class for a Joomla admin Controller. It handles add, edit, delete,
publish, unpublish records....
*/
class AdminController extends Controller
{
/**
* The URL view item variable.
*
* @var string
*/
protected $viewItem;
/**
* The URL view list variable.
*
* @var string
*/
protected $viewList;
/**
* Constructor.
*
* @param array $config An optional associative array of configuration
settings.
*
* @see OSFControlleAdmin
*/
public function __construct(Container $container, array $config =
array())
{
parent::__construct($container, $config);
if (isset($config['view_item']))
{
$this->viewItem = $config['view_item'];
}
else
{
$this->viewItem = $this->name;
}
if (isset($config['view_list']))
{
$this->viewList = $config['view_list'];
}
else
{
$this->viewList =
$this->container->inflector->pluralize($this->viewItem);
}
// Register tasks mapping
$this->registerTask('apply', 'save');
$this->registerTask('save2new', 'save');
$this->registerTask('save2copy', 'save');
$this->registerTask('unpublish', 'publish');
$this->registerTask('orderup', 'reorder');
$this->registerTask('orderdown', 'reorder');
}
/**
* Display Form allows adding a new record
*/
public function add()
{
if ($this->allowAdd())
{
$this->input->set('view', $this->viewItem);
$this->input->set('edit', false);
$this->display();
}
else
{
$this->setMessage(JText::_('JLIB_APPLICATION_ERROR_CREATE_RECORD_NOT_PERMITTED'),
'error');
$this->setRedirect(JRoute::_($this->getViewListUrl(), false));
return false;
}
}
/**
* Display Form allows editing record
*/
public function edit()
{
$cid = $this->input->get('cid', array(),
'array');
if (count($cid))
{
$this->input->set('id', 0);
}
if ($this->allowEdit(array('id' =>
$this->input->getInt('id'))))
{
$this->input->set('view', $this->viewItem);
$this->input->set('edit', false);
$this->display();
}
else
{
$this->setMessage(JText::_('JLIB_APPLICATION_ERROR_EDIT_NOT_PERMITTED'),
'error');
$this->setRedirect(JRoute::_($this->getViewListUrl(), false));
}
}
/**
* Method to save a record.
*
* @return boolean True if successful, false otherwise.
*
*/
public function save()
{
$this->csrfProtection();
$input = $this->input;
$task = $this->getTask();
if ($task == 'save2copy')
{
$input->set('source_id', $input->getInt('id',
0));
$input->set('id', 0);
$task = 'apply';
}
$id = $input->getInt('id', 0);
if ($this->allowSave(array('id' => $id)))
{
try
{
/* @var \OSL\Model\AdminModel $model */
$model = $this->getModel();
$model->store($this->input);
if ($this->container->app->isClient('site')
&& $id == 0)
{
$langSuffix = '_SUBMIT_SAVE_SUCCESS';
}
else
{
$langSuffix = '_SAVE_SUCCESS';
}
$languagePrefix = $this->container->languagePrefix;
$msg =
JText::_(($this->container->language->hasKey($languagePrefix .
$langSuffix) ? $languagePrefix : 'JLIB_APPLICATION') .
$langSuffix);
switch ($task)
{
case 'apply':
$url =
JRoute::_($this->getViewItemUrl($input->getInt('id', 0)),
false);
break;
case 'save2new':
$url = JRoute::_($this->getViewItemUrl(), false);
break;
default:
$url = JRoute::_($this->getViewListUrl(), false);
break;
}
$this->setRedirect($url, $msg);
}
catch (\Exception $e)
{
$this->setMessage($e->getMessage(), 'error');
$this->setRedirect(JRoute::_($this->getViewItemUrl($id),
false));
}
}
else
{
$this->setMessage(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'),
'error');
$this->setRedirect(JRoute::_($this->getViewListUrl(), false));
}
}
/**
* Method to cancel an add/edit. We simply redirect users to view which
display list of records
*
*/
public function cancel()
{
$this->setRedirect(JRoute::_($this->getViewListUrl(), false));
}
/**
* Delete selected items
*
* @return void
*
*/
public function delete()
{
// Check for request forgeries
$this->csrfProtection();
// Get items to remove from the request.
$cid = $this->input->get('cid', array(),
'array');
$cid = ArrayHelper::toInteger($cid);
for ($i = 0, $n = count($cid); $i < $n; $i++)
{
if (!$this->allowDelete($cid[$i]))
{
unset($cid[$i]);
}
}
$languagePrefix = $this->container->languagePrefix;
if (count($cid))
{
try
{
/* @var \OSL\Model\AdminModel $model */
$model = $this->getModel($this->name,
array('ignore_request' => true));
$model->delete($cid);
$this->setMessage(JText::plural($languagePrefix .
'_N_ITEMS_DELETED', count($cid)));
}
catch (\Exception $e)
{
$this->setMessage($e->getMessage(), 'error');
}
}
else
{
$this->setMessage($languagePrefix . '_NO_ITEM_SELECTED',
'warning');
}
$this->setRedirect(JRoute::_($this->getViewListUrl(), false));
}
/**
* Method to publish a list of items
*
* @return void
*/
public function publish()
{
// Check for request forgeries
$this->csrfProtection();
// Get items to publish from the request.
$cid = $this->input->get('cid', array(),
'array');
$data = array('publish' => 1, 'unpublish'
=> 0, 'archive' => 2);
$task = $this->getTask();
$published = ArrayHelper::getValue($data, $task, 0, 'int');
$cid = ArrayHelper::toInteger($cid);
for ($i = 0, $n = count($cid); $i < $n; $i++)
{
if (!$this->allowEditState($cid[$i]))
{
unset($cid[$i]);
}
}
$languagePrefix = $this->container->languagePrefix;
if (count($cid))
{
try
{
/* @var \OSL\Model\AdminModel $model */
$model = $this->getModel($this->name,
array('ignore_request' => true));
$model->publish($cid, $published);
switch ($published)
{
case 0:
$ntext = $languagePrefix . '_N_ITEMS_UNPUBLISHED';
break;
case 1:
$ntext = $languagePrefix . '_N_ITEMS_PUBLISHED';
break;
case 2:
$ntext = $languagePrefix . '_N_ITEMS_ARCHIVED';
break;
}
$this->setMessage(JText::plural($ntext, count($cid)));
}
catch (\Exception $e)
{
$msg = null;
$this->setMessage($e->getMessage(), 'error');
}
}
else
{
$this->setMessage($languagePrefix . '_NO_ITEM_SELECTED',
'warning');
}
$this->setRedirect(JRoute::_($this->getViewListUrl(), false));
}
/**
* Method to save the submitted ordering values for records via AJAX.
*
* @return void
*
* @since 2.0
*/
public function save_order_ajax()
{
// Get the input
$pks = $this->input->post->get('cid', array(),
'array');
$order = $this->input->post->get('order', array(),
'array');
// Sanitize the input
$pks = ArrayHelper::toInteger($pks);
$order = ArrayHelper::toInteger($order);
// Get the model
/* @var \OSL\Model\AdminModel $model */
$model = $this->getModel();
// Save the ordering
$return = $model->saveorder($pks, $order);
if ($return)
{
echo "1";
}
// Close the application
$this->container->app->close();
}
/**
* Method to check if you can add a new record.
*
* Extended classes can override this if necessary.
*
* @param array $data An array of input data.
*
* @return boolean
*
*/
protected function allowAdd($data = array())
{
return
$this->container->user->authorise('core.create',
$this->container->option);
}
/**
* Method to check if you can edit a new record.
*
* Extended classes can override this if necessary.
*
* @param array $data An array of input data.
* @param string $key The name of the key for the primary key; default
is id.
*
* @return boolean
*/
protected function allowEdit($data = array(), $key = 'id')
{
return $this->container->user->authorise('core.edit',
$this->container->option);
}
/**
* Method to check if you can save a new or existing record.
*
* Extended classes can override this if necessary.
*
* @param array $data An array of input data.
* @param string $key The name of the key for the primary key.
*
* @return boolean
*/
protected function allowSave($data, $key = 'id')
{
$recordId = isset($data[$key]) ? $data[$key] : '0';
if ($recordId)
{
return $this->allowEdit($data, $key);
}
else
{
return $this->allowAdd($data);
}
}
/**
* Method to check whether the current user is allowed to delete a record
*
* @param int $id Record ID
*
* @return boolean True if allowed to delete the record. Defaults to the
permission for the component.
*
*/
protected function allowDelete($id)
{
return
$this->container->user->authorise('core.delete',
$this->container->option);
}
/**
* Method to check whether the current user can change status (publish,
unpublish of a record)
*
* @param int $id Id of the record
*
* @return boolean True if allowed to change the state of the record.
Defaults to the permission for the component.
*
*/
protected function allowEditState($id)
{
return
$this->container->user->authorise('core.edit.state',
$this->container->option);
}
/**
* Get url of the page which display list of records
*
* @return string
*/
protected function getViewListUrl()
{
return 'index.php?option=' . $this->container->option .
'&view=' . $this->viewList;
}
/**
* Get url of the page which allow adding/editing a record
*
* @param int $recordId
*
* @return string
*/
protected function getViewItemUrl($recordId = null)
{
$url = 'index.php?option=' . $this->container->option .
'&view=' . $this->viewItem;
if ($recordId)
{
$url .= '&id=' . $recordId;
}
return $url;
}
}Controller.php000064400000030153151156604430007407 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\Controller;
use ReflectionClass, ReflectionMethod, Exception;
use OSL\Container\Container,
OSL\Input\Input;
defined('_JEXEC') or die;
/**
* Class Controller
*
* Base class for a Joomla Controller. Controller (Controllers are where
you put all the actual code.) Provides basic
* functionality, such as rendering views (aka displaying templates).
*/
class Controller
{
/**
* Array which hold all the controller objects has been created
*
* @var array
*/
protected static $instances = [];
/**
* Name of the controller
*
* @var string
*/
protected $name;
/**
* Controller input
*
* @var Input
*/
protected $input;
/**
* Array of class methods
*
* @var array
*/
protected $methods = [];
/**
* Array which map a task with the method will be called
*
* @var array
*/
protected $taskMap = [];
/**
* Current or most recently performed task.
*
* @var string
*/
protected $task;
/**
* URL for redirection.
*
* @var string
*/
protected $redirect;
/**
* Redirect message.
*
* @var string
*/
protected $message = null;
/**
* Redirect message type.
*
* @var string
*/
protected $messageType = 'message';
/**
* Method to get instance of a controller
*
* @param Container $container
* @param array $config
*
* @return Controller
*
* @throws Exception
*/
public static function getInstance(Container $container, array $config =
[])
{
$input = $container->input;
// Handle task format controller.task
$task = $input->get('task', '');
$lou= $input->get('layout', null);
if ($task== $lou)
{
$task= '';
}
$pos = strpos($task, '.');
if ($pos !== false)
{
$name = substr($task, 0, $pos);
$task = substr($task, $pos + 1);
$input->set('task', $task);
}
else
{
$name =
$container->inflector->singularize($input->getCmd('view'));
if (empty($name))
{
$name = 'controller';
}
}
$option = $container->option;
if (!isset(self::$instances[$option . $name]))
{
$config['name'] = $name;
if ($task == '')
{
// Always use default controller for display task
if (class_exists($container->namespace .
'\\Override\\Controller\\Controller'))
{
$className = $container->namespace .
'\\Override\\Controller\\Controller';
}
else
{
$className = $container->namespace .
'\\Controller\\Controller';
}
self::$instances[$option . $name] = new $className($container,
$config);
}
else
{
self::$instances[$option . $name] =
$container->factory->createController($name, $config);
}
}
return self::$instances[$option . $name];
}
/**
* Constructor.
*
* @param Container $container
*
* @param array $config An optional associative array of
configuration settings.
*
* @throws Exception
*/
public function __construct(Container $container, array $config = [])
{
$this->container = $container;
$input = $container->input;
// Build the default taskMap based on the class methods
$xMethods = get_class_methods('\\OSL\\Controller\Controller');
$r = new ReflectionClass($this);
$rMethods = $r->getMethods(ReflectionMethod::IS_PUBLIC);
foreach ($rMethods as $rMethod)
{
$mName = $rMethod->getName();
if (!in_array($mName, $xMethods) || $mName == 'display')
{
$this->taskMap[strtolower($mName)] = $mName;
$this->methods[] = strtolower($mName);
}
}
// Register controller default task
if (isset($config['default_task']))
{
$this->registerTask('__default',
$config['default_task']);
}
else
{
$this->registerTask('__default', 'display');
}
$this->name = $config['name'];
$this->input = $input;
$this->task = $input->getCmd('task',
'display');
$lou= $input->get('layout', null);
if ($this->task== $lou)
{
$this->task= '';
}
}
/**
* Execute the given task
*
* @return $this return itself to support changing
*
* @throws Exception
*/
public function execute()
{
$task = strtolower($this->task);
if (empty($task))
{
$task = 'display';
}
if (isset($this->taskMap[$task]))
{
$this->task = $task;
$doTask = $this->taskMap[$task];
$this->$doTask();
return $this;
}
throw new
Exception(\JText::sprintf('JLIB_APPLICATION_ERROR_TASK_NOT_FOUND',
$task), 404);
}
/**
* Method to display a view
*
* This function is provide as a default implementation, in most cases
* you will need to override it in your own controllers.
*
* @param boolean $cachable If true, the view output will be cached
*
* @param array $urlparams An array of safe url parameters and their
variable types, for valid values see {@link JFilterInput::clean()}.
*
* @return Controller A RADController object to support chaining.
*/
public function display($cachable = false, array $urlparams = [])
{
$document = $this->container->document;
if ($document instanceof \JDocument)
{
$viewType = $document->getType();
}
else
{
$viewType = $this->input->getCmd('format',
'html');
}
$viewName = $this->input->get('view',
$this->container->defaultView);
$viewLayout = $this->input->get('layout',
'default');
// Create view object
$view = $this->getView($viewName, $viewType, $viewLayout);
// If view has model, create the model, and assign it to the view
if ($view->hasModel)
{
$model = $this->getModel($viewName);
$view->setModel($model);
}
// Render the view
$view->display();
return $this;
}
/**
* Method to get a model object, loading it if required.
*
* @param string $name The model name. Optional. Default will be the
controller name
*
* @param array $config Configuration array for model. Optional.
*
* @return \OSL\Model\Model The model.
*/
public function getModel($name = '', array $config = [])
{
// If name is not given, the model will has same name with controller
if (empty($name))
{
$name = $this->name;
}
$model = $this->container->factory->createModel($name,
$config);
// Populate model state from request data
$model->populateState();
return $model;
}
/**
* Method to get instance of a view
*
* @param string $name The view name
* @param string $type The view type
* @param string $layout The view layout
*
* @param array $config Configuration array for view. Optional.
*
* @return \OSL\View\HtmlView Reference to the view
*/
public function getView($name, $type = 'html', $layout =
'default', array $config = [])
{
// Merge config array with default config parameters
$config['layout'] = $layout;
$config['input'] = $this->input;
if (!\JFolder::exists(JPATH_BASE . '/components/' .
$this->container->option . '/View/' . ucfirst($name)))
{
throw new \Exception(\JText::sprintf('View %s not found',
$name), 404);
}
if ($this->container->app->isClient('administrator'))
{
$config['is_admin_view'] = true;
}
// Set the default paths for finding the layout if it is not specified in
the $config array
if (empty($config['paths']))
{
$paths = [];
$paths[] = JPATH_THEMES . '/' .
$this->container->template . '/html/' .
$this->container->option . '/' . ucfirst($name);
$paths[] = JPATH_BASE . '/components/' .
$this->container->option . '/View/' . ucfirst($name) .
'/tmpl';
$config['paths'] = $paths;
}
return $this->container->factory->createView($name, $type,
$config);
}
/**
* Sets the internal message that is passed with a redirect
*
* @param string $text Message to display on redirect.
*
* @param string $type Message type. Optional, defaults to
'message'.
*
* @return string Previous message
*/
public function setMessage($text, $type = 'message')
{
$previous = $this->message;
$this->message = $text;
$this->messageType = $type;
return $previous;
}
/**
* Set a URL for browser redirection.
*
* @param string $url URL to redirect to.
*
* @param string $msg Message to display on redirect. Optional,
defaults to value set internally by controller, if any.
*
* @param string $type Message type. Optional, defaults to
'message' or the type set by a previous call to setMessage.
*
* @return Controller This object to support chaining.
*/
public function setRedirect($url, $msg = null, $type = null)
{
$this->redirect = $url;
if ($msg !== null)
{
// Controller may have set this directly
$this->message = $msg;
}
// Ensure the type is not overwritten by a previous call to setMessage.
if (empty($type))
{
if (empty($this->messageType))
{
$this->messageType = 'message';
}
}
// If the type is explicitly set, set it.
else
{
$this->messageType = $type;
}
return $this;
}
/**
* Redirects the browser or returns false if no redirect is set.
*
* @return boolean False if no redirect exists.
*/
public function redirect()
{
if ($this->redirect)
{
/* @var \JApplicationCms $app */
$app = $this->container->get('app');
$app->enqueueMessage($this->message, $this->messageType);
$app->redirect($this->redirect);
}
return false;
}
/**
* Register (map) a task to a method in the class.
*
* @param string $task The task name
*
* @param string $method The name of the method in the derived class
to perform for this task.
*
* @return Controller A Controller object to support chaining.
*/
public function registerTask($task, $method)
{
if (in_array(strtolower($method), $this->methods))
{
$this->taskMap[strtolower($task)] = $method;
}
return $this;
}
/**
* Get the application object.
*
* @return \JApplicationCms The application object.
*/
public function getApplication()
{
return $this->container->get('app');
}
/**
* Get the input object.
*
* @return Input The input object.
*/
public function getInput()
{
return $this->container->get('input');
}
/**
* Set controller input
*
* @param Input $input
*
* @return Input
*/
public function setInput(Input $input)
{
$currentInput = $this->input;
$this->input = $input;
$this->container->set('input', $input);
$this->task = $input->getCmd('task',
'display');
return $currentInput;
}
/**
* Get the last task that is being performed or was most recently
performed.
*
* @return string The task that is being performed or was most recently
performed.
*/
public function getTask()
{
return $this->task;
}
/**
* Set the task for controller
*
* @param $task
*/
public function setTask($task)
{
$this->task = $task;
}
/**
* Magic get method. Handles magic properties:
* $this->app mapped to $this->container->app
* $this->input mapped to $this->container->input
*
* @param string $name The property to fetch
*
* @return mixed|null
*/
public function __get($name)
{
$magicProperties = [
'app',
'option',
];
if (in_array($name, $magicProperties))
{
return $this->container->get($name);
}
// Property not found; raise error
$trace = debug_backtrace();
trigger_error(
'Undefined property via __get(): ' . $name .
' in ' . $trace[0]['file'] .
' on line ' . $trace[0]['line'],
E_USER_NOTICE);
return null;
}
/**
* Check token to prevent CSRF attack
*/
protected function csrfProtection($method = 'post')
{
\JSession::checkToken($method) or
die(\JText::_('JINVALID_TOKEN'));
}
}Download.php000064400000205156151156604430007042 0ustar00<?php
/**
* @package RAD
* @subpackage Controller
*
* @copyright Copyright (C) 2015 Ossolution Team, Inc. All rights
reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
namespace OSL\Controller;
defined('_JEXEC') or die;
trait Download
{
/**
* Standard method to download file
*
* @param string $filePath
* @param string $filename
* @param bool $inline
*/
protected function processDownloadFile($filePath, $filename = null,
$inline = false)
{
/* @var JApplicationCms $app */
$app = $this->getApplication();
if (!$filename)
{
$filename = basename($filePath);
}
$mimeType = $this->getMineType($filename);
if (is_array($mimeType))
{
$mimeType = $mimeType[0];
}
$fileSize = @filesize($filePath);
if ($inline)
{
$contentDisposition = 'inline';
}
else
{
$contentDisposition = 'attachment';
}
while (@ob_end_clean()) ;
@clearstatcache();
$app->setHeader('Content-Type', $mimeType, true)
->setHeader('Content-Disposition', $contentDisposition .
'; filename="' . $filename . '"', true)
->setHeader('Content-Transfer-Encoding',
'binary', true);
if ($fileSize > 0)
{
$app->setHeader('Content-Length', $fileSize, true);
}
// Disable Cache
$app->setHeader('Cache-Control', 'must-revalidate,
post-check=0, pre-check=0', true)
->setHeader('Expires', '0', true)
->setHeader('Pragma', 'no-cache', true);
$app->sendHeaders();
flush();
if (!$fileSize)
{
// If the filesize is not reported, hope that readfile works
@readfile($filePath);
}
else
{
// If the filesize is reported, use 1M chunks for echoing the data to
the browser
$blocksize = 1048576; //1M chunks
$handle = @fopen($filePath, "r");
// Now we need to loop through the file and echo out chunks of file
data
if ($handle !== false)
{
while (!@feof($handle))
{
echo @fread($handle, $blocksize);
@ob_flush();
flush();
}
}
if ($handle !== false)
{
@fclose($handle);
}
}
$app->close();
}
/**
* Get mimetype for a given filename
*
* @param $fileExt
*/
protected function getMineType($filename)
{
$mimeTypes = [
'3dm' => ['x-world/x-3dmf'],
'3dmf' => ['x-world/x-3dmf'],
'3dml' => ['text/vnd.in3d.3dml'],
'3ds' => ['image/x-3ds'],
'3g2' => ['video/3gpp2'],
'3gp' => ['video/3gpp'],
'7z' =>
['application/x-7z-compressed'],
'a' => ['application/octet-stream'],
'aab' =>
['application/x-authorware-bin'],
'aac' => ['audio/x-aac'],
'aam' =>
['application/x-authorware-map'],
'aas' =>
['application/x-authorware-seg'],
'abc' => ['text/vnd.abc'],
'abw' => ['application/x-abiword'],
'ac' =>
['application/pkix-attr-cert'],
'acc' =>
['application/vnd.americandynamics.acc'],
'ace' =>
['application/x-ace-compressed'],
'acgi' => ['text/html'],
'acu' => ['application/vnd.acucobol'],
'acutc' => ['application/vnd.acucorp'],
'adp' => ['audio/adpcm'],
'aep' =>
['application/vnd.audiograph'],
'afl' => ['video/animaflex'],
'afm' => ['application/x-font-type1'],
'afp' =>
['application/vnd.ibm.modcap'],
'ahead' =>
['application/vnd.ahead.space'],
'ai' => ['application/postscript'],
'aif' => ['audio/aiff',
'audio/x-aiff'],
'aifc' => ['audio/aiff',
'audio/x-aiff'],
'aiff' => ['audio/aiff',
'audio/x-aiff'],
'aim' => ['application/x-aim'],
'aip' => ['text/x-audiosoft-intra'],
'air' =>
['application/vnd.adobe.air-application-installer-package+zip'],
'ait' => ['application/vnd.dvb.ait'],
'ami' => ['application/vnd.amiga.ami'],
'ani' =>
['application/x-navi-animation'],
'aos' =>
['application/x-nokia-9000-communicator-add-on-software'],
'apk' =>
['application/vnd.android.package-archive'],
'appcache' => ['text/cache-manifest'],
'application' =>
['application/x-ms-application'],
'apr' =>
['application/vnd.lotus-approach'],
'aps' => ['application/mime'],
'arc' => ['application/x-freearc'],
'arj' => ['application/arj',
'application/octet-stream'],
'art' => ['image/x-jg'],
'asc' => ['application/pgp-signature'],
'asf' => ['video/x-ms-asf'],
'asm' => ['text/x-asm'],
'aso' =>
['application/vnd.accpac.simply.aso'],
'asp' => ['text/asp'],
'asx' => ['application/x-mplayer2',
'video/x-ms-asf', 'video/x-ms-asf-plugin'],
'atc' => ['application/vnd.acucorp'],
'atom' => ['application/atom+xml'],
'atomcat' => ['application/atomcat+xml'],
'atomsvc' => ['application/atomsvc+xml'],
'atx' =>
['application/vnd.antix.game-component'],
'au' => ['audio/basic'],
'avi' => ['application/x-troff-msvideo',
'video/avi', 'video/msvideo',
'video/x-msvideo'],
'avs' => ['video/avs-video'],
'aw' => ['application/applixware'],
'azf' =>
['application/vnd.airzip.filesecure.azf'],
'azs' =>
['application/vnd.airzip.filesecure.azs'],
'azw' =>
['application/vnd.amazon.ebook'],
'bat' => ['application/x-msdownload'],
'bcpio' => ['application/x-bcpio'],
'bdf' => ['application/x-font-bdf'],
'bdm' =>
['application/vnd.syncml.dm+wbxml'],
'bed' =>
['application/vnd.realvnc.bed'],
'bh2' =>
['application/vnd.fujitsu.oasysprs'],
'bin' => ['application/mac-binary',
'application/macbinary', 'application/octet-stream',
'application/x-binary', 'application/x-macbinary'],
'blb' => ['application/x-blorb'],
'blorb' => ['application/x-blorb'],
'bm' => ['image/bmp'],
'bmi' => ['application/vnd.bmi'],
'bmp' => ['image/bmp',
'image/x-windows-bmp'],
'boo' => ['application/book'],
'book' =>
['application/vnd.framemaker'],
'box' =>
['application/vnd.previewsystems.box'],
'boz' => ['application/x-bzip2'],
'bpk' => ['application/octet-stream'],
'bsh' => ['application/x-bsh'],
'btif' => ['image/prs.btif'],
'buffer' => ['application/octet-stream'],
'bz' => ['application/x-bzip'],
'bz2' => ['application/x-bzip2'],
'c' => ['text/x-c'],
'c++' => ['text/plain'],
'c11amc' =>
['application/vnd.cluetrust.cartomobile-config'],
'c11amz' =>
['application/vnd.cluetrust.cartomobile-config-pkg'],
'c4d' =>
['application/vnd.clonk.c4group'],
'c4f' =>
['application/vnd.clonk.c4group'],
'c4g' =>
['application/vnd.clonk.c4group'],
'c4p' =>
['application/vnd.clonk.c4group'],
'c4u' =>
['application/vnd.clonk.c4group'],
'cab' =>
['application/vnd.ms-cab-compressed'],
'caf' => ['audio/x-caf'],
'cap' =>
['application/vnd.tcpdump.pcap'],
'car' => ['application/vnd.curl.car'],
'cat' =>
['application/vnd.ms-pki.seccat'],
'cb7' => ['application/x-cbr'],
'cba' => ['application/x-cbr'],
'cbr' => ['application/x-cbr'],
'cbt' => ['application/x-cbr'],
'cbz' => ['application/x-cbr'],
'cc' => ['text/plain',
'text/x-c'],
'ccad' => ['application/clariscad'],
'cco' => ['application/x-cocoa'],
'cct' => ['application/x-director'],
'ccxml' => ['application/ccxml+xml'],
'cdbcmsg' =>
['application/vnd.contact.cmsg'],
'cdf' => ['application/cdf',
'application/x-cdf', 'application/x-netcdf'],
'cdkey' =>
['application/vnd.mediastation.cdkey'],
'cdmia' =>
['application/cdmi-capability'],
'cdmic' =>
['application/cdmi-container'],
'cdmid' => ['application/cdmi-domain'],
'cdmio' => ['application/cdmi-object'],
'cdmiq' => ['application/cdmi-queue'],
'cdx' => ['chemical/x-cdx'],
'cdxml' =>
['application/vnd.chemdraw+xml'],
'cdy' =>
['application/vnd.cinderella'],
'cer' => ['application/pkix-cert',
'application/x-x509-ca-cert'],
'cfs' =>
['application/x-cfs-compressed'],
'cgm' => ['image/cgm'],
'cha' => ['application/x-chat'],
'chat' => ['application/x-chat'],
'chm' =>
['application/vnd.ms-htmlhelp'],
'chrt' =>
['application/vnd.kde.kchart'],
'cif' => ['chemical/x-cif'],
'cii' =>
['application/vnd.anser-web-certificate-issue-initiation'],
'cil' =>
['application/vnd.ms-artgalry'],
'cla' => ['application/vnd.claymore'],
'class' => ['application/java',
'application/java-byte-code',
'application/x-java-class'],
'clkk' =>
['application/vnd.crick.clicker.keyboard'],
'clkp' =>
['application/vnd.crick.clicker.palette'],
'clkt' =>
['application/vnd.crick.clicker.template'],
'clkw' =>
['application/vnd.crick.clicker.wordbank'],
'clkx' =>
['application/vnd.crick.clicker'],
'clp' => ['application/x-msclip'],
'cmc' =>
['application/vnd.cosmocaller'],
'cmdf' => ['chemical/x-cmdf'],
'cml' => ['chemical/x-cml'],
'cmp' =>
['application/vnd.yellowriver-custom-menu'],
'cmx' => ['image/x-cmx'],
'cod' => ['application/vnd.rim.cod'],
'com' => ['application/octet-stream',
'text/plain'],
'conf' => ['text/plain'],
'cpio' => ['application/x-cpio'],
'cpp' => ['text/x-c'],
'cpt' => ['application/x-compactpro',
'application/x-cpt'],
'crd' => ['application/x-mscardfile'],
'crl' => ['application/pkcs-crl',
'application/pkix-crl'],
'crt' => ['application/pkix-cert',
'application/x-x509-ca-cert',
'application/x-x509-user-cert'],
'crx' =>
['application/x-chrome-extension'],
'cryptonote' =>
['application/vnd.rig.cryptonote'],
'csh' => ['application/x-csh',
'text/x-script.csh'],
'csml' => ['chemical/x-csml'],
'csp' =>
['application/vnd.commonspace'],
'css' => ['application/x-pointplus',
'text/css'],
'cst' => ['application/x-director'],
'csv' => ['text/csv'],
'cu' => ['application/cu-seeme'],
'curl' => ['text/vnd.curl'],
'cww' => ['application/prs.cww'],
'cxt' => ['application/x-director'],
'cxx' => ['text/x-c'],
'dae' => ['model/vnd.collada+xml'],
'daf' =>
['application/vnd.mobius.daf'],
'dart' => ['application/vnd.dart'],
'dataless' => ['application/vnd.fdsn.seed'],
'davmount' => ['application/davmount+xml'],
'dbk' => ['application/docbook+xml'],
'dcr' => ['application/x-director'],
'dcurl' => ['text/vnd.curl.dcurl'],
'dd2' =>
['application/vnd.oma.dd2+xml'],
'ddd' =>
['application/vnd.fujixerox.ddd'],
'deb' =>
['application/x-debian-package'],
'deepv' => ['application/x-deepv'],
'def' => ['text/plain'],
'deploy' => ['application/octet-stream'],
'der' =>
['application/x-x509-ca-cert'],
'dfac' =>
['application/vnd.dreamfactory'],
'dgc' =>
['application/x-dgc-compressed'],
'dic' => ['text/x-c'],
'dif' => ['video/x-dv'],
'diff' => ['text/plain'],
'dir' => ['application/x-director'],
'dis' =>
['application/vnd.mobius.dis'],
'dist' => ['application/octet-stream'],
'distz' => ['application/octet-stream'],
'djv' => ['image/vnd.djvu'],
'djvu' => ['image/vnd.djvu'],
'dl' => ['video/dl',
'video/x-dl'],
'dll' => ['application/x-msdownload'],
'dmg' =>
['application/x-apple-diskimage'],
'dmp' =>
['application/vnd.tcpdump.pcap'],
'dms' => ['application/octet-stream'],
'dna' => ['application/vnd.dna'],
'doc' => ['application/msword'],
'docm' =>
['application/vnd.ms-word.document.macroenabled.12'],
'docx' =>
['application/vnd.openxmlformats-officedocument.wordprocessingml.document'],
'dot' => ['application/msword'],
'dotm' =>
['application/vnd.ms-word.template.macroenabled.12'],
'dotx' =>
['application/vnd.openxmlformats-officedocument.wordprocessingml.template'],
'dp' => ['application/vnd.osgi.dp'],
'dpg' => ['application/vnd.dpgraph'],
'dra' => ['audio/vnd.dra'],
'drw' => ['application/drafting'],
'dsc' => ['text/prs.lines.tag'],
'dssc' => ['application/dssc+der'],
'dtb' => ['application/x-dtbook+xml'],
'dtd' => ['application/xml-dtd'],
'dts' => ['audio/vnd.dts'],
'dtshd' => ['audio/vnd.dts.hd'],
'dump' => ['application/octet-stream'],
'dv' => ['video/x-dv'],
'dvb' => ['video/vnd.dvb.file'],
'dvi' => ['application/x-dvi'],
'dwf' => ['drawing/x-dwf (old)',
'model/vnd.dwf'],
'dwg' => ['application/acad',
'image/vnd.dwg', 'image/x-dwg'],
'dxf' => ['image/vnd.dxf'],
'dxp' =>
['application/vnd.spotfire.dxp'],
'dxr' => ['application/x-director'],
'ecelp4800' => ['audio/vnd.nuera.ecelp4800'],
'ecelp7470' => ['audio/vnd.nuera.ecelp7470'],
'ecelp9600' => ['audio/vnd.nuera.ecelp9600'],
'ecma' => ['application/ecmascript'],
'edm' =>
['application/vnd.novadigm.edm'],
'edx' =>
['application/vnd.novadigm.edx'],
'efif' => ['application/vnd.picsel'],
'ei6' => ['application/vnd.pg.osasli'],
'el' => ['text/x-script.elisp'],
'elc' => ['application/x-bytecode.elisp
(compiled elisp)', 'application/x-elc'],
'emf' => ['application/x-msmetafile'],
'eml' => ['message/rfc822'],
'emma' => ['application/emma+xml'],
'emz' => ['application/x-msmetafile'],
'env' => ['application/x-envoy'],
'eol' => ['audio/vnd.digital-winds'],
'eot' =>
['application/vnd.ms-fontobject'],
'eps' => ['application/postscript'],
'epub' => ['application/epub+zip'],
'es' => ['application/x-esrehber'],
'es3' =>
['application/vnd.eszigno3+xml'],
'esa' =>
['application/vnd.osgi.subsystem'],
'esf' => ['application/vnd.epson.esf'],
'et3' =>
['application/vnd.eszigno3+xml'],
'etx' => ['text/x-setext'],
'eva' => ['application/x-eva'],
'event-stream' => ['text/event-stream'],
'evy' => ['application/envoy',
'application/x-envoy'],
'exe' => ['application/x-msdownload'],
'exi' => ['application/exi'],
'ext' =>
['application/vnd.novadigm.ext'],
'ez' => ['application/andrew-inset'],
'ez2' =>
['application/vnd.ezpix-album'],
'ez3' =>
['application/vnd.ezpix-package'],
'f' => ['text/plain',
'text/x-fortran'],
'f4v' => ['video/x-f4v'],
'f77' => ['text/x-fortran'],
'f90' => ['text/plain',
'text/x-fortran'],
'fbs' => ['image/vnd.fastbidsheet'],
'fcdt' =>
['application/vnd.adobe.formscentral.fcdt'],
'fcs' => ['application/vnd.isac.fcs'],
'fdf' => ['application/vnd.fdf'],
'fe_launch' =>
['application/vnd.denovo.fcselayout-link'],
'fg5' =>
['application/vnd.fujitsu.oasysgp'],
'fgd' => ['application/x-director'],
'fh' => ['image/x-freehand'],
'fh4' => ['image/x-freehand'],
'fh5' => ['image/x-freehand'],
'fh7' => ['image/x-freehand'],
'fhc' => ['image/x-freehand'],
'fif' => ['application/fractals',
'image/fif'],
'fig' => ['application/x-xfig'],
'flac' => ['audio/flac'],
'fli' => ['video/fli',
'video/x-fli'],
'flo' =>
['application/vnd.micrografx.flo'],
'flv' => ['video/x-flv'],
'flw' => ['application/vnd.kde.kivio'],
'flx' => ['text/vnd.fmi.flexstor'],
'fly' => ['text/vnd.fly'],
'fm' =>
['application/vnd.framemaker'],
'fmf' => ['video/x-atomic3d-feature'],
'fnc' =>
['application/vnd.frogans.fnc'],
'for' => ['text/plain',
'text/x-fortran'],
'fpx' => ['image/vnd.fpx',
'image/vnd.net-fpx'],
'frame' =>
['application/vnd.framemaker'],
'frl' => ['application/freeloader'],
'fsc' =>
['application/vnd.fsc.weblaunch'],
'fst' => ['image/vnd.fst'],
'ftc' =>
['application/vnd.fluxtime.clip'],
'fti' =>
['application/vnd.anser-web-funds-transfer-initiation'],
'funk' => ['audio/make'],
'fvt' => ['video/vnd.fvt'],
'fxp' => ['application/vnd.adobe.fxp'],
'fxpl' => ['application/vnd.adobe.fxp'],
'fzs' =>
['application/vnd.fuzzysheet'],
'g' => ['text/plain'],
'g2w' => ['application/vnd.geoplan'],
'g3' => ['image/g3fax'],
'g3w' => ['application/vnd.geospace'],
'gac' =>
['application/vnd.groove-account'],
'gam' => ['application/x-tads'],
'gbr' =>
['application/rpki-ghostbusters'],
'gca' =>
['application/x-gca-compressed'],
'gdl' => ['model/vnd.gdl'],
'geo' => ['application/vnd.dynageo'],
'gex' =>
['application/vnd.geometry-explorer'],
'ggb' =>
['application/vnd.geogebra.file'],
'ggt' =>
['application/vnd.geogebra.tool'],
'ghf' =>
['application/vnd.groove-help'],
'gif' => ['image/gif'],
'gim' =>
['application/vnd.groove-identity-message'],
'gl' => ['video/gl',
'video/x-gl'],
'gml' => ['application/gml+xml'],
'gmx' => ['application/vnd.gmx'],
'gnumeric' => ['application/x-gnumeric'],
'gph' =>
['application/vnd.flographit'],
'gpx' => ['application/gpx+xml'],
'gqf' => ['application/vnd.grafeq'],
'gqs' => ['application/vnd.grafeq'],
'gram' => ['application/srgs'],
'gramps' => ['application/x-gramps-xml'],
'gre' =>
['application/vnd.geometry-explorer'],
'grv' =>
['application/vnd.groove-injector'],
'grxml' => ['application/srgs+xml'],
'gsd' => ['audio/x-gsm'],
'gsf' =>
['application/x-font-ghostscript'],
'gsm' => ['audio/x-gsm'],
'gsp' => ['application/x-gsp'],
'gss' => ['application/x-gss'],
'gtar' => ['application/x-gtar'],
'gtm' =>
['application/vnd.groove-tool-message'],
'gtw' => ['model/vnd.gtw'],
'gv' => ['text/vnd.graphviz'],
'gxf' => ['application/gxf'],
'gxt' => ['application/vnd.geonext'],
'gz' => ['application/x-compressed',
'application/x-gzip'],
'gzip' => ['application/x-gzip',
'multipart/x-gzip'],
'h' => ['text/plain',
'text/x-h'],
'h261' => ['video/h261'],
'h263' => ['video/h263'],
'h264' => ['video/h264'],
'hal' => ['application/vnd.hal+xml'],
'hbci' => ['application/vnd.hbci'],
'hdf' => ['application/x-hdf'],
'help' => ['application/x-helpfile'],
'hgl' => ['application/vnd.hp-hpgl'],
'hh' => ['text/plain',
'text/x-h'],
'hlb' => ['text/x-script'],
'hlp' => ['application/hlp',
'application/x-helpfile', 'application/x-winhelp'],
'hpg' => ['application/vnd.hp-hpgl'],
'hpgl' => ['application/vnd.hp-hpgl'],
'hpid' => ['application/vnd.hp-hpid'],
'hps' => ['application/vnd.hp-hps'],
'hqx' => ['application/binhex',
'application/binhex4', 'application/mac-binhex',
'application/mac-binhex40', 'application/x-binhex40',
'application/x-mac-binhex40'],
'hta' => ['application/hta'],
'htc' => ['text/x-component'],
'htke' =>
['application/vnd.kenameaapp'],
'htm' => ['text/html'],
'html' => ['text/html'],
'htmls' => ['text/html'],
'htt' => ['text/webviewhtml'],
'htx' => ['text/html'],
'hvd' =>
['application/vnd.yamaha.hv-dic'],
'hvp' =>
['application/vnd.yamaha.hv-voice'],
'hvs' =>
['application/vnd.yamaha.hv-script'],
'i2g' => ['application/vnd.intergeo'],
'icc' =>
['application/vnd.iccprofile'],
'ice' => ['x-conference/x-cooltalk'],
'icm' =>
['application/vnd.iccprofile'],
'ico' => ['image/x-icon'],
'ics' => ['text/calendar'],
'idc' => ['text/plain'],
'ief' => ['image/ief'],
'iefs' => ['image/ief'],
'ifb' => ['text/calendar'],
'ifm' =>
['application/vnd.shana.informed.formdata'],
'iges' => ['application/iges',
'model/iges'],
'igl' => ['application/vnd.igloader'],
'igm' =>
['application/vnd.insors.igm'],
'igs' => ['application/iges',
'model/iges'],
'igx' =>
['application/vnd.micrografx.igx'],
'iif' =>
['application/vnd.shana.informed.interchange'],
'ima' => ['application/x-ima'],
'imap' => ['application/x-httpd-imap'],
'imp' =>
['application/vnd.accpac.simply.imp'],
'ims' => ['application/vnd.ms-ims'],
'in' => ['text/plain'],
'inf' => ['application/inf'],
'ink' => ['application/inkml+xml'],
'inkml' => ['application/inkml+xml'],
'ins' =>
['application/x-internett-signup'],
'install' =>
['application/x-install-instructions'],
'iota' =>
['application/vnd.astraea-software.iota'],
'ip' => ['application/x-ip2'],
'ipfix' => ['application/ipfix'],
'ipk' =>
['application/vnd.shana.informed.package'],
'irm' =>
['application/vnd.ibm.rights-management'],
'irp' =>
['application/vnd.irepository.package+xml'],
'iso' =>
['application/x-iso9660-image'],
'isu' => ['video/x-isvideo'],
'it' => ['audio/it'],
'itp' =>
['application/vnd.shana.informed.formtemplate'],
'iv' => ['application/x-inventor'],
'ivp' =>
['application/vnd.immervision-ivp'],
'ivr' => ['i-world/i-vrml'],
'ivu' =>
['application/vnd.immervision-ivu'],
'ivy' => ['application/x-livescreen'],
'jad' =>
['text/vnd.sun.j2me.app-descriptor'],
'jam' => ['application/vnd.jam'],
'jar' => ['application/java-archive'],
'jav' => ['text/plain',
'text/x-java-source'],
'java' => ['text/plain',
'text/x-java-source'],
'jcm' =>
['application/x-java-commerce'],
'jfif' => ['image/jpeg',
'image/pjpeg'],
'jfif-tbnl' => ['image/jpeg'],
'jisp' => ['application/vnd.jisp'],
'jlt' => ['application/vnd.hp-jlyt'],
'jnlp' =>
['application/x-java-jnlp-file'],
'joda' =>
['application/vnd.joost.joda-archive'],
'jpe' => ['image/jpeg',
'image/pjpeg'],
'jpeg' => ['image/jpeg',
'image/pjpeg'],
'jpg' => ['image/jpeg',
'image/pjpeg'],
'jpgm' => ['video/jpm'],
'jpgv' => ['video/jpeg'],
'jpm' => ['video/jpm'],
'jps' => ['image/x-jps'],
'js' => ['application/javascript'],
'json' => ['application/json',
'text/plain'],
'jsonml' => ['application/jsonml+json'],
'jut' => ['image/jutvision'],
'kar' => ['audio/midi',
'music/x-karaoke'],
'karbon' =>
['application/vnd.kde.karbon'],
'kfo' =>
['application/vnd.kde.kformula'],
'kia' =>
['application/vnd.kidspiration'],
'kil' =>
['application/x-killustrator'],
'kml' =>
['application/vnd.google-earth.kml+xml'],
'kmz' =>
['application/vnd.google-earth.kmz'],
'kne' => ['application/vnd.kinar'],
'knp' => ['application/vnd.kinar'],
'kon' =>
['application/vnd.kde.kontour'],
'kpr' =>
['application/vnd.kde.kpresenter'],
'kpt' =>
['application/vnd.kde.kpresenter'],
'kpxx' =>
['application/vnd.ds-keypoint'],
'ksh' => ['application/x-ksh',
'text/x-script.ksh'],
'ksp' =>
['application/vnd.kde.kspread'],
'ktr' => ['application/vnd.kahootz'],
'ktx' => ['image/ktx'],
'ktz' => ['application/vnd.kahootz'],
'kwd' => ['application/vnd.kde.kword'],
'kwt' => ['application/vnd.kde.kword'],
'la' => ['audio/nspaudio',
'audio/x-nspaudio'],
'lam' => ['audio/x-liveaudio'],
'lasxml' =>
['application/vnd.las.las+xml'],
'latex' => ['application/x-latex'],
'lbd' =>
['application/vnd.llamagraphics.life-balance.desktop'],
'lbe' =>
['application/vnd.llamagraphics.life-balance.exchange+xml'],
'les' =>
['application/vnd.hhe.lesson-player'],
'lha' => ['application/lha',
'application/octet-stream', 'application/x-lha'],
'lhx' => ['application/octet-stream'],
'link66' =>
['application/vnd.route66.link66+xml'],
'list' => ['text/plain'],
'list3820' =>
['application/vnd.ibm.modcap'],
'listafp' =>
['application/vnd.ibm.modcap'],
'lma' => ['audio/nspaudio',
'audio/x-nspaudio'],
'lnk' => ['application/x-ms-shortcut'],
'log' => ['text/plain'],
'lostxml' => ['application/lost+xml'],
'lrf' => ['application/octet-stream'],
'lrm' => ['application/vnd.ms-lrm'],
'lsp' => ['application/x-lisp',
'text/x-script.lisp'],
'lst' => ['text/plain'],
'lsx' => ['text/x-la-asf'],
'ltf' =>
['application/vnd.frogans.ltf'],
'ltx' => ['application/x-latex'],
'lua' => ['text/x-lua'],
'luac' =>
['application/x-lua-bytecode'],
'lvp' => ['audio/vnd.lucent.voice'],
'lwp' =>
['application/vnd.lotus-wordpro'],
'lzh' => ['application/octet-stream',
'application/x-lzh'],
'lzx' => ['application/lzx',
'application/octet-stream', 'application/x-lzx'],
'm' => ['text/plain',
'text/x-m'],
'm13' => ['application/x-msmediaview'],
'm14' => ['application/x-msmediaview'],
'm1v' => ['video/mpeg'],
'm21' => ['application/mp21'],
'm2a' => ['audio/mpeg'],
'm2v' => ['video/mpeg'],
'm3a' => ['audio/mpeg'],
'm3u' => ['audio/x-mpegurl'],
'm3u8' => ['application/x-mpegURL'],
'm4a' => ['audio/mp4'],
'm4p' => ['application/mp4'],
'm4u' => ['video/vnd.mpegurl'],
'm4v' => ['video/x-m4v'],
'ma' => ['application/mathematica'],
'mads' => ['application/mads+xml'],
'mag' =>
['application/vnd.ecowin.chart'],
'maker' =>
['application/vnd.framemaker'],
'man' => ['text/troff'],
'manifest' => ['text/cache-manifest'],
'map' => ['application/x-navimap'],
'mar' => ['application/octet-stream'],
'markdown' => ['text/x-markdown'],
'mathml' => ['application/mathml+xml'],
'mb' => ['application/mathematica'],
'mbd' => ['application/mbedlet'],
'mbk' =>
['application/vnd.mobius.mbk'],
'mbox' => ['application/mbox'],
'mc' =>
['application/x-magic-cap-package-1.0'],
'mc1' =>
['application/vnd.medcalcdata'],
'mcd' => ['application/mcad',
'application/x-mathcad'],
'mcf' => ['image/vasa',
'text/mcf'],
'mcp' => ['application/netmc'],
'mcurl' => ['text/vnd.curl.mcurl'],
'md' => ['text/x-markdown'],
'mdb' => ['application/x-msaccess'],
'mdi' => ['image/vnd.ms-modi'],
'me' => ['text/troff'],
'mesh' => ['model/mesh'],
'meta4' => ['application/metalink4+xml'],
'metalink' => ['application/metalink+xml'],
'mets' => ['application/mets+xml'],
'mfm' => ['application/vnd.mfmp'],
'mft' => ['application/rpki-manifest'],
'mgp' =>
['application/vnd.osgeo.mapguide.package'],
'mgz' =>
['application/vnd.proteus.magazine'],
'mht' => ['message/rfc822'],
'mhtml' => ['message/rfc822'],
'mid' => ['application/x-midi',
'audio/midi', 'audio/x-mid', 'audio/x-midi',
'music/crescendo', 'x-music/x-midi'],
'midi' => ['application/x-midi',
'audio/midi', 'audio/x-mid', 'audio/x-midi',
'music/crescendo', 'x-music/x-midi'],
'mie' => ['application/x-mie'],
'mif' => ['application/x-frame',
'application/x-mif'],
'mime' => ['message/rfc822',
'www/mime'],
'mj2' => ['video/mj2'],
'mjf' =>
['audio/x-vnd.audioexplosion.mjuicemediafile'],
'mjp2' => ['video/mj2'],
'mjpg' => ['video/x-motion-jpeg'],
'mk3d' => ['video/x-matroska'],
'mka' => ['audio/x-matroska'],
'mkd' => ['text/x-markdown'],
'mks' => ['video/x-matroska'],
'mkv' => ['video/x-matroska'],
'mlp' => ['application/vnd.dolby.mlp'],
'mm' => ['application/base64',
'application/x-meme'],
'mmd' =>
['application/vnd.chipnuts.karaoke-mmd'],
'mme' => ['application/base64'],
'mmf' => ['application/vnd.smaf'],
'mmr' =>
['image/vnd.fujixerox.edmics-mmr'],
'mng' => ['video/x-mng'],
'mny' => ['application/x-msmoney'],
'mobi' =>
['application/x-mobipocket-ebook'],
'mod' => ['audio/mod',
'audio/x-mod'],
'mods' => ['application/mods+xml'],
'moov' => ['video/quicktime'],
'mov' => ['video/quicktime'],
'movie' => ['video/x-sgi-movie'],
'mp2' => ['audio/mpeg',
'audio/x-mpeg', 'video/mpeg', 'video/x-mpeg',
'video/x-mpeq2a'],
'mp21' => ['application/mp21'],
'mp2a' => ['audio/mpeg'],
'mp3' => ['audio/mpeg3',
'audio/x-mpeg-3', 'video/mpeg',
'video/x-mpeg'],
'mp4' => ['video/mp4'],
'mp4a' => ['audio/mp4'],
'mp4s' => ['application/mp4'],
'mp4v' => ['video/mp4'],
'mpa' => ['audio/mpeg',
'video/mpeg'],
'mpc' =>
['application/vnd.mophun.certificate'],
'mpe' => ['video/mpeg'],
'mpeg' => ['video/mpeg'],
'mpg' => ['audio/mpeg',
'video/mpeg'],
'mpg4' => ['video/mp4'],
'mpga' => ['audio/mpeg'],
'mpkg' =>
['application/vnd.apple.installer+xml'],
'mpm' =>
['application/vnd.blueice.multipass'],
'mpn' =>
['application/vnd.mophun.application'],
'mpp' =>
['application/vnd.ms-project'],
'mpt' =>
['application/vnd.ms-project'],
'mpv' => ['application/x-project'],
'mpx' => ['application/x-project'],
'mpy' =>
['application/vnd.ibm.minipay'],
'mqy' =>
['application/vnd.mobius.mqy'],
'mrc' => ['application/marc'],
'mrcx' => ['application/marcxml+xml'],
'ms' => ['text/troff'],
'mscml' =>
['application/mediaservercontrol+xml'],
'mseed' =>
['application/vnd.fdsn.mseed'],
'mseq' => ['application/vnd.mseq'],
'msf' => ['application/vnd.epson.msf'],
'msh' => ['model/mesh'],
'msi' => ['application/x-msdownload'],
'msl' =>
['application/vnd.mobius.msl'],
'msty' =>
['application/vnd.muvee.style'],
'mts' => ['model/vnd.mts'],
'mus' => ['application/vnd.musician'],
'musicxml' =>
['application/vnd.recordare.musicxml+xml'],
'mv' => ['video/x-sgi-movie'],
'mvb' => ['application/x-msmediaview'],
'mwf' => ['application/vnd.mfer'],
'mxf' => ['application/mxf'],
'mxl' =>
['application/vnd.recordare.musicxml'],
'mxml' => ['application/xv+xml'],
'mxs' =>
['application/vnd.triscape.mxs'],
'mxu' => ['video/vnd.mpegurl'],
'my' => ['audio/make'],
'mzz' =>
['application/x-vnd.audioexplosion.mzz'],
'n-gage' =>
['application/vnd.nokia.n-gage.symbian.install'],
'n3' => ['text/n3'],
'nap' => ['image/naplps'],
'naplps' => ['image/naplps'],
'nb' => ['application/mathematica'],
'nbp' =>
['application/vnd.wolfram.player'],
'nc' => ['application/x-netcdf'],
'ncm' =>
['application/vnd.nokia.configuration-message'],
'ncx' => ['application/x-dtbncx+xml'],
'nfo' => ['text/x-nfo'],
'ngdat' =>
['application/vnd.nokia.n-gage.data'],
'nif' => ['image/x-niff'],
'niff' => ['image/x-niff'],
'nitf' => ['application/vnd.nitf'],
'nix' =>
['application/x-mix-transfer'],
'nlu' =>
['application/vnd.neurolanguage.nlu'],
'nml' => ['application/vnd.enliven'],
'nnd' =>
['application/vnd.noblenet-directory'],
'nns' =>
['application/vnd.noblenet-sealer'],
'nnw' =>
['application/vnd.noblenet-web'],
'npx' => ['image/vnd.net-fpx'],
'nsc' => ['application/x-conference'],
'nsf' =>
['application/vnd.lotus-notes'],
'ntf' => ['application/vnd.nitf'],
'nvd' => ['application/x-navidoc'],
'nws' => ['message/rfc822'],
'nzb' => ['application/x-nzb'],
'o' => ['application/octet-stream'],
'oa2' =>
['application/vnd.fujitsu.oasys2'],
'oa3' =>
['application/vnd.fujitsu.oasys3'],
'oas' =>
['application/vnd.fujitsu.oasys'],
'obd' => ['application/x-msbinder'],
'obj' => ['application/x-tgif'],
'oda' => ['application/oda'],
'odb' =>
['application/vnd.oasis.opendocument.database'],
'odc' =>
['application/vnd.oasis.opendocument.chart'],
'odf' =>
['application/vnd.oasis.opendocument.formula'],
'odft' =>
['application/vnd.oasis.opendocument.formula-template'],
'odg' =>
['application/vnd.oasis.opendocument.graphics'],
'odi' =>
['application/vnd.oasis.opendocument.image'],
'odm' =>
['application/vnd.oasis.opendocument.text-master'],
'odp' =>
['application/vnd.oasis.opendocument.presentation'],
'ods' =>
['application/vnd.oasis.opendocument.spreadsheet'],
'odt' =>
['application/vnd.oasis.opendocument.text'],
'oga' => ['audio/ogg'],
'ogg' => ['audio/ogg'],
'ogv' => ['video/ogg'],
'ogx' => ['application/ogg'],
'omc' => ['application/x-omc'],
'omcd' =>
['application/x-omcdatamaker'],
'omcr' =>
['application/x-omcregerator'],
'omdoc' => ['application/omdoc+xml'],
'onepkg' => ['application/onenote'],
'onetmp' => ['application/onenote'],
'onetoc' => ['application/onenote'],
'onetoc2' => ['application/onenote'],
'opf' =>
['application/oebps-package+xml'],
'opml' => ['text/x-opml'],
'oprc' => ['application/vnd.palm'],
'org' =>
['application/vnd.lotus-organizer'],
'osf' =>
['application/vnd.yamaha.openscoreformat'],
'osfpvg' =>
['application/vnd.yamaha.openscoreformat.osfpvg+xml'],
'otc' =>
['application/vnd.oasis.opendocument.chart-template'],
'otf' => ['font/opentype'],
'otg' =>
['application/vnd.oasis.opendocument.graphics-template'],
'oth' =>
['application/vnd.oasis.opendocument.text-web'],
'oti' =>
['application/vnd.oasis.opendocument.image-template'],
'otm' =>
['application/vnd.oasis.opendocument.text-master'],
'otp' =>
['application/vnd.oasis.opendocument.presentation-template'],
'ots' =>
['application/vnd.oasis.opendocument.spreadsheet-template'],
'ott' =>
['application/vnd.oasis.opendocument.text-template'],
'oxps' => ['application/oxps'],
'oxt' =>
['application/vnd.openofficeorg.extension'],
'p' => ['text/x-pascal'],
'p10' => ['application/pkcs10',
'application/x-pkcs10'],
'p12' => ['application/pkcs-12',
'application/x-pkcs12'],
'p7a' =>
['application/x-pkcs7-signature'],
'p7b' =>
['application/x-pkcs7-certificates'],
'p7c' => ['application/pkcs7-mime',
'application/x-pkcs7-mime'],
'p7m' => ['application/pkcs7-mime',
'application/x-pkcs7-mime'],
'p7r' =>
['application/x-pkcs7-certreqresp'],
'p7s' =>
['application/pkcs7-signature'],
'p8' => ['application/pkcs8'],
'part' => ['application/pro_eng'],
'pas' => ['text/x-pascal'],
'paw' => ['application/vnd.pawaafile'],
'pbd' =>
['application/vnd.powerbuilder6'],
'pbm' => ['image/x-portable-bitmap'],
'pcap' =>
['application/vnd.tcpdump.pcap'],
'pcf' => ['application/x-font-pcf'],
'pcl' => ['application/vnd.hp-pcl',
'application/x-pcl'],
'pclxl' => ['application/vnd.hp-pclxl'],
'pct' => ['image/x-pict'],
'pcurl' =>
['application/vnd.curl.pcurl'],
'pcx' => ['image/x-pcx'],
'pdb' => ['application/vnd.palm'],
'pdf' => ['application/pdf'],
'pfa' => ['application/x-font-type1'],
'pfb' => ['application/x-font-type1'],
'pfm' => ['application/x-font-type1'],
'pfr' => ['application/font-tdpfr'],
'pfunk' => ['audio/make'],
'pfx' => ['application/x-pkcs12'],
'pgm' => ['image/x-portable-graymap'],
'pgn' => ['application/x-chess-pgn'],
'pgp' => ['application/pgp-encrypted'],
'php' => ['text/x-php'],
'pic' => ['image/x-pict'],
'pict' => ['image/pict'],
'pkg' => ['application/octet-stream'],
'pki' => ['application/pkixcmp'],
'pkipath' => ['application/pkix-pkipath'],
'pko' =>
['application/vnd.ms-pki.pko'],
'pl' => ['text/plain',
'text/x-script.perl'],
'plb' =>
['application/vnd.3gpp.pic-bw-large'],
'plc' =>
['application/vnd.mobius.plc'],
'plf' =>
['application/vnd.pocketlearn'],
'pls' => ['application/pls+xml'],
'plx' => ['application/x-pixclscript'],
'pm' => ['image/x-xpixmap',
'text/x-script.perl-module'],
'pm4' => ['application/x-pagemaker'],
'pm5' => ['application/x-pagemaker'],
'pml' => ['application/vnd.ctc-posml'],
'png' => ['image/png'],
'pnm' =>
['application/x-portable-anymap',
'image/x-portable-anymap'],
'portpkg' =>
['application/vnd.macports.portpkg'],
'pot' => ['application/mspowerpoint',
'application/vnd.ms-powerpoint'],
'potm' =>
['application/vnd.ms-powerpoint.template.macroenabled.12'],
'potx' =>
['application/vnd.openxmlformats-officedocument.presentationml.template'],
'pov' => ['model/x-pov'],
'ppa' =>
['application/vnd.ms-powerpoint'],
'ppam' =>
['application/vnd.ms-powerpoint.addin.macroenabled.12'],
'ppd' => ['application/vnd.cups-ppd'],
'ppm' => ['image/x-portable-pixmap'],
'pps' => ['application/mspowerpoint',
'application/vnd.ms-powerpoint'],
'ppsm' =>
['application/vnd.ms-powerpoint.slideshow.macroenabled.12'],
'ppsx' =>
['application/vnd.openxmlformats-officedocument.presentationml.slideshow'],
'ppt' => ['application/mspowerpoint',
'application/powerpoint',
'application/vnd.ms-powerpoint',
'application/x-mspowerpoint'],
'pptm' =>
['application/vnd.ms-powerpoint.presentation.macroenabled.12'],
'pptx' =>
['application/vnd.openxmlformats-officedocument.presentationml.presentation'],
'ppz' => ['application/mspowerpoint'],
'pqa' => ['application/vnd.palm'],
'prc' =>
['application/x-mobipocket-ebook'],
'pre' =>
['application/vnd.lotus-freelance'],
'prf' => ['application/pics-rules'],
'prt' => ['application/pro_eng'],
'ps' => ['application/postscript'],
'psb' =>
['application/vnd.3gpp.pic-bw-small'],
'psd' => ['image/vnd.adobe.photoshop'],
'psf' =>
['application/x-font-linux-psf'],
'pskcxml' => ['application/pskc+xml'],
'ptid' => ['application/vnd.pvi.ptid1'],
'pub' => ['application/x-mspublisher'],
'pvb' =>
['application/vnd.3gpp.pic-bw-var'],
'pvu' => ['paleovu/x-pv'],
'pwn' =>
['application/vnd.3m.post-it-notes'],
'pwz' =>
['application/vnd.ms-powerpoint'],
'py' => ['text/x-script.phyton'],
'pya' =>
['audio/vnd.ms-playready.media.pya'],
'pyc' =>
['applicaiton/x-bytecode.python'],
'pyo' => ['application/x-python-code'],
'pyv' =>
['video/vnd.ms-playready.media.pyv'],
'qam' =>
['application/vnd.epson.quickanime'],
'qbo' => ['application/vnd.intu.qbo'],
'qcp' => ['audio/vnd.qcelp'],
'qd3' => ['x-world/x-3dmf'],
'qd3d' => ['x-world/x-3dmf'],
'qfx' => ['application/vnd.intu.qfx'],
'qif' => ['image/x-quicktime'],
'qps' =>
['application/vnd.publishare-delta-tree'],
'qt' => ['video/quicktime'],
'qtc' => ['video/x-qtc'],
'qti' => ['image/x-quicktime'],
'qtif' => ['image/x-quicktime'],
'qwd' =>
['application/vnd.quark.quarkxpress'],
'qwt' =>
['application/vnd.quark.quarkxpress'],
'qxb' =>
['application/vnd.quark.quarkxpress'],
'qxd' =>
['application/vnd.quark.quarkxpress'],
'qxl' =>
['application/vnd.quark.quarkxpress'],
'qxt' =>
['application/vnd.quark.quarkxpress'],
'ra' => ['audio/x-pn-realaudio',
'audio/x-pn-realaudio-plugin', 'audio/x-realaudio'],
'ram' => ['audio/x-pn-realaudio'],
'rar' =>
['application/x-rar-compressed'],
'ras' => ['application/x-cmu-raster',
'image/cmu-raster', 'image/x-cmu-raster'],
'rast' => ['image/cmu-raster'],
'rcprofile' =>
['application/vnd.ipunplugged.rcprofile'],
'rdf' => ['application/rdf+xml'],
'rdz' =>
['application/vnd.data-vision.rdz'],
'rep' =>
['application/vnd.businessobjects'],
'res' =>
['application/x-dtbresource+xml'],
'rexx' => ['text/x-script.rexx'],
'rf' => ['image/vnd.rn-realflash'],
'rgb' => ['image/x-rgb'],
'rif' => ['application/reginfo+xml'],
'rip' => ['audio/vnd.rip'],
'ris' =>
['application/x-research-info-systems'],
'rl' =>
['application/resource-lists+xml'],
'rlc' =>
['image/vnd.fujixerox.edmics-rlc'],
'rld' =>
['application/resource-lists-diff+xml'],
'rm' =>
['application/vnd.rn-realmedia',
'audio/x-pn-realaudio'],
'rmi' => ['audio/midi'],
'rmm' => ['audio/x-pn-realaudio'],
'rmp' => ['audio/x-pn-realaudio',
'audio/x-pn-realaudio-plugin'],
'rms' =>
['application/vnd.jcp.javame.midlet-rms'],
'rmvb' =>
['application/vnd.rn-realmedia-vbr'],
'rnc' =>
['application/relax-ng-compact-syntax'],
'rng' => ['application/ringing-tones',
'application/vnd.nokia.ringing-tone'],
'rnx' =>
['application/vnd.rn-realplayer'],
'roa' => ['application/rpki-roa'],
'roff' => ['text/troff'],
'rp' => ['image/vnd.rn-realpix'],
'rp9' =>
['application/vnd.cloanto.rp9'],
'rpm' =>
['audio/x-pn-realaudio-plugin'],
'rpss' =>
['application/vnd.nokia.radio-presets'],
'rpst' =>
['application/vnd.nokia.radio-preset'],
'rq' => ['application/sparql-query'],
'rs' =>
['application/rls-services+xml'],
'rsd' => ['application/rsd+xml'],
'rss' => ['application/rss+xml'],
'rt' => ['text/richtext',
'text/vnd.rn-realtext'],
'rtf' => ['application/rtf',
'application/x-rtf', 'text/richtext'],
'rtx' => ['application/rtf',
'text/richtext'],
'rv' => ['video/vnd.rn-realvideo'],
's' => ['text/x-asm'],
's3m' => ['audio/s3m'],
'saf' =>
['application/vnd.yamaha.smaf-audio'],
'saveme' => ['aapplication/octet-stream'],
'sbk' => ['application/x-tbook'],
'sbml' => ['application/sbml+xml'],
'sc' =>
['application/vnd.ibm.secure-container'],
'scd' => ['application/x-msschedule'],
'scm' =>
['application/x-lotusscreencam', 'text/x-script.guile',
'text/x-script.scheme', 'video/x-scm'],
'scq' =>
['application/scvp-cv-request'],
'scs' =>
['application/scvp-cv-response'],
'scurl' => ['text/vnd.curl.scurl'],
'sda' =>
['application/vnd.stardivision.draw'],
'sdc' =>
['application/vnd.stardivision.calc'],
'sdd' =>
['application/vnd.stardivision.impress'],
'sdkd' =>
['application/vnd.solent.sdkm+xml'],
'sdkm' =>
['application/vnd.solent.sdkm+xml'],
'sdml' => ['text/plain'],
'sdp' => ['application/sdp',
'application/x-sdp'],
'sdr' => ['application/sounder'],
'sdw' =>
['application/vnd.stardivision.writer'],
'sea' => ['application/sea',
'application/x-sea'],
'see' => ['application/vnd.seemail'],
'seed' => ['application/vnd.fdsn.seed'],
'sema' => ['application/vnd.sema'],
'semd' => ['application/vnd.semd'],
'semf' => ['application/vnd.semf'],
'ser' =>
['application/java-serialized-object'],
'set' => ['application/set'],
'setpay' =>
['application/set-payment-initiation'],
'setreg' =>
['application/set-registration-initiation'],
'sfd-hdstx' =>
['application/vnd.hydrostatix.sof-data'],
'sfs' =>
['application/vnd.spotfire.sfs'],
'sfv' => ['text/x-sfv'],
'sgi' => ['image/sgi'],
'sgl' =>
['application/vnd.stardivision.writer-global'],
'sgm' => ['text/sgml',
'text/x-sgml'],
'sgml' => ['text/sgml',
'text/x-sgml'],
'sh' => ['application/x-bsh',
'application/x-sh', 'application/x-shar',
'text/x-script.sh'],
'shar' => ['application/x-bsh',
'application/x-shar'],
'shf' => ['application/shf+xml'],
'shtml' => ['text/html',
'text/x-server-parsed-html'],
'si' => ['text/vnd.wap.si'],
'sic' => ['application/vnd.wap.sic'],
'sid' => ['image/x-mrsid-image'],
'sig' => ['application/pgp-signature'],
'sil' => ['audio/silk'],
'silo' => ['model/mesh'],
'sis' =>
['application/vnd.symbian.install'],
'sisx' =>
['application/vnd.symbian.install'],
'sit' => ['application/x-sit',
'application/x-stuffit'],
'sitx' => ['application/x-stuffitx'],
'skd' => ['application/vnd.koan'],
'skm' => ['application/vnd.koan'],
'skp' => ['application/vnd.koan'],
'skt' => ['application/vnd.koan'],
'sl' => ['application/x-seelogo'],
'slc' => ['application/vnd.wap.slc'],
'sldm' =>
['application/vnd.ms-powerpoint.slide.macroenabled.12'],
'sldx' =>
['application/vnd.openxmlformats-officedocument.presentationml.slide'],
'slt' =>
['application/vnd.epson.salt'],
'sm' =>
['application/vnd.stepmania.stepchart'],
'smf' =>
['application/vnd.stardivision.math'],
'smi' => ['application/smil+xml'],
'smil' => ['application/smil+xml'],
'smv' => ['video/x-smv'],
'smzip' =>
['application/vnd.stepmania.package'],
'snd' => ['audio/basic',
'audio/x-adpcm'],
'snf' => ['application/x-font-snf'],
'so' => ['application/octet-stream'],
'sol' => ['application/solids'],
'spc' =>
['application/x-pkcs7-certificates', 'text/x-speech'],
'spf' =>
['application/vnd.yamaha.smaf-phrase'],
'spl' =>
['application/x-futuresplash'],
'spot' => ['text/vnd.in3d.spot'],
'spp' =>
['application/scvp-vp-response'],
'spq' =>
['application/scvp-vp-request'],
'spr' => ['application/x-sprite'],
'sprite' => ['application/x-sprite'],
'spx' => ['audio/ogg'],
'sql' => ['application/x-sql'],
'src' => ['application/x-wais-source'],
'srt' => ['application/x-subrip'],
'sru' => ['application/sru+xml'],
'srx' =>
['application/sparql-results+xml'],
'ssdl' => ['application/ssdl+xml'],
'sse' =>
['application/vnd.kodak-descriptor'],
'ssf' => ['application/vnd.epson.ssf'],
'ssi' => ['text/x-server-parsed-html'],
'ssm' =>
['application/streamingmedia'],
'ssml' => ['application/ssml+xml'],
'sst' =>
['application/vnd.ms-pki.certstore'],
'st' =>
['application/vnd.sailingtracker.track'],
'stc' =>
['application/vnd.sun.xml.calc.template'],
'std' =>
['application/vnd.sun.xml.draw.template'],
'step' => ['application/step'],
'stf' => ['application/vnd.wt.stf'],
'sti' =>
['application/vnd.sun.xml.impress.template'],
'stk' => ['application/hyperstudio'],
'stl' => ['application/sla',
'application/vnd.ms-pki.stl',
'application/x-navistyle'],
'stp' => ['application/step'],
'str' => ['application/vnd.pg.format'],
'stw' =>
['application/vnd.sun.xml.writer.template'],
'sub' => ['text/vnd.dvb.subtitle'],
'sus' =>
['application/vnd.sus-calendar'],
'susp' =>
['application/vnd.sus-calendar'],
'sv4cpio' => ['application/x-sv4cpio'],
'sv4crc' => ['application/x-sv4crc'],
'svc' =>
['application/vnd.dvb.service'],
'svd' => ['application/vnd.svd'],
'svf' => ['image/vnd.dwg',
'image/x-dwg'],
'svg' => ['image/svg+xml'],
'svgz' => ['image/svg+xml'],
'svr' => ['application/x-world',
'x-world/x-svr'],
'swa' => ['application/x-director'],
'swf' =>
['application/x-shockwave-flash'],
'swi' =>
['application/vnd.aristanetworks.swi'],
'sxc' =>
['application/vnd.sun.xml.calc'],
'sxd' =>
['application/vnd.sun.xml.draw'],
'sxg' =>
['application/vnd.sun.xml.writer.global'],
'sxi' =>
['application/vnd.sun.xml.impress'],
'sxm' =>
['application/vnd.sun.xml.math'],
'sxw' =>
['application/vnd.sun.xml.writer'],
't' => ['text/troff'],
't3' => ['application/x-t3vm-image'],
'taglet' => ['application/vnd.mynfc'],
'talk' => ['text/x-speech'],
'tao' =>
['application/vnd.tao.intent-module-archive'],
'tar' => ['application/x-tar'],
'tbk' => ['application/toolbook',
'application/x-tbook'],
'tcap' =>
['application/vnd.3gpp2.tcap'],
'tcl' => ['application/x-tcl',
'text/x-script.tcl'],
'tcsh' => ['text/x-script.tcsh'],
'teacher' =>
['application/vnd.smart.teacher'],
'tei' => ['application/tei+xml'],
'teicorpus' => ['application/tei+xml'],
'tex' => ['application/x-tex'],
'texi' => ['application/x-texinfo'],
'texinfo' => ['application/x-texinfo'],
'text' => ['application/plain',
'text/plain'],
'tfi' => ['application/thraud+xml'],
'tfm' => ['application/x-tex-tfm'],
'tga' => ['image/x-tga'],
'tgz' => ['application/gnutar',
'application/x-compressed'],
'thmx' =>
['application/vnd.ms-officetheme'],
'tif' => ['image/tiff',
'image/x-tiff'],
'tiff' => ['image/tiff',
'image/x-tiff'],
'tmo' =>
['application/vnd.tmobile-livetv'],
'torrent' => ['application/x-bittorrent'],
'tpl' =>
['application/vnd.groove-tool-template'],
'tpt' => ['application/vnd.trid.tpt'],
'tr' => ['text/troff'],
'tra' => ['application/vnd.trueapp'],
'trm' => ['application/x-msterminal'],
'ts' => ['video/MP2T'],
'tsd' =>
['application/timestamped-data'],
'tsi' => ['audio/tsp-audio'],
'tsp' => ['application/dsptype',
'audio/tsplayer'],
'tsv' => ['text/tab-separated-values'],
'ttc' => ['application/x-font-ttf'],
'ttf' => ['application/x-font-ttf'],
'ttl' => ['text/turtle'],
'turbot' => ['image/florian'],
'twd' =>
['application/vnd.simtech-mindmapper'],
'twds' =>
['application/vnd.simtech-mindmapper'],
'txd' =>
['application/vnd.genomatix.tuxedo'],
'txf' =>
['application/vnd.mobius.txf'],
'txt' => ['text/plain'],
'u32' =>
['application/x-authorware-bin'],
'udeb' =>
['application/x-debian-package'],
'ufd' => ['application/vnd.ufdl'],
'ufdl' => ['application/vnd.ufdl'],
'uil' => ['text/x-uil'],
'ulx' => ['application/x-glulx'],
'umj' => ['application/vnd.umajin'],
'uni' => ['text/uri-list'],
'unis' => ['text/uri-list'],
'unityweb' => ['application/vnd.unity'],
'unv' => ['application/i-deas'],
'uoml' => ['application/vnd.uoml+xml'],
'uri' => ['text/uri-list'],
'uris' => ['text/uri-list'],
'urls' => ['text/uri-list'],
'ustar' => ['application/x-ustar',
'multipart/x-ustar'],
'utz' => ['application/vnd.uiq.theme'],
'uu' => ['application/octet-stream',
'text/x-uuencode'],
'uue' => ['text/x-uuencode'],
'uva' => ['audio/vnd.dece.audio'],
'uvd' => ['application/vnd.dece.data'],
'uvf' => ['application/vnd.dece.data'],
'uvg' => ['image/vnd.dece.graphic'],
'uvh' => ['video/vnd.dece.hd'],
'uvi' => ['image/vnd.dece.graphic'],
'uvm' => ['video/vnd.dece.mobile'],
'uvp' => ['video/vnd.dece.pd'],
'uvs' => ['video/vnd.dece.sd'],
'uvt' =>
['application/vnd.dece.ttml+xml'],
'uvu' => ['video/vnd.uvvu.mp4'],
'uvv' => ['video/vnd.dece.video'],
'uvva' => ['audio/vnd.dece.audio'],
'uvvd' => ['application/vnd.dece.data'],
'uvvf' => ['application/vnd.dece.data'],
'uvvg' => ['image/vnd.dece.graphic'],
'uvvh' => ['video/vnd.dece.hd'],
'uvvi' => ['image/vnd.dece.graphic'],
'uvvm' => ['video/vnd.dece.mobile'],
'uvvp' => ['video/vnd.dece.pd'],
'uvvs' => ['video/vnd.dece.sd'],
'uvvt' =>
['application/vnd.dece.ttml+xml'],
'uvvu' => ['video/vnd.uvvu.mp4'],
'uvvv' => ['video/vnd.dece.video'],
'uvvx' =>
['application/vnd.dece.unspecified'],
'uvvz' => ['application/vnd.dece.zip'],
'uvx' =>
['application/vnd.dece.unspecified'],
'uvz' => ['application/vnd.dece.zip'],
'vcard' => ['text/vcard'],
'vcd' => ['application/x-cdlink'],
'vcf' => ['text/x-vcard'],
'vcg' =>
['application/vnd.groove-vcard'],
'vcs' => ['text/x-vcalendar'],
'vcx' => ['application/vnd.vcx'],
'vda' => ['application/vda'],
'vdo' => ['video/vdo'],
'vew' => ['application/groupwise'],
'vis' => ['application/vnd.visionary'],
'viv' => ['video/vivo',
'video/vnd.vivo'],
'vivo' => ['video/vivo',
'video/vnd.vivo'],
'vmd' =>
['application/vocaltec-media-desc'],
'vmf' =>
['application/vocaltec-media-file'],
'vob' => ['video/x-ms-vob'],
'voc' => ['audio/voc',
'audio/x-voc'],
'vor' =>
['application/vnd.stardivision.writer'],
'vos' => ['video/vosaic'],
'vox' =>
['application/x-authorware-bin'],
'vqe' => ['audio/x-twinvq-plugin'],
'vqf' => ['audio/x-twinvq'],
'vql' => ['audio/x-twinvq-plugin'],
'vrml' => ['application/x-vrml',
'model/vrml', 'x-world/x-vrml'],
'vrt' => ['x-world/x-vrt'],
'vsd' => ['application/vnd.visio'],
'vsf' => ['application/vnd.vsf'],
'vss' => ['application/vnd.visio'],
'vst' => ['application/vnd.visio'],
'vsw' => ['application/vnd.visio'],
'vtt' => ['text/vtt'],
'vtu' => ['model/vnd.vtu'],
'vxml' => ['application/voicexml+xml'],
'w3d' => ['application/x-director'],
'w60' =>
['application/wordperfect6.0'],
'w61' =>
['application/wordperfect6.1'],
'w6w' => ['application/msword'],
'wad' => ['application/x-doom'],
'wav' => ['audio/wav',
'audio/x-wav'],
'wax' => ['audio/x-ms-wax'],
'wb1' => ['application/x-qpro'],
'wbmp' => ['image/vnd.wap.wbmp'],
'wbs' =>
['application/vnd.criticaltools.wbs+xml'],
'wbxml' => ['application/vnd.wap.wbxml'],
'wcm' => ['application/vnd.ms-works'],
'wdb' => ['application/vnd.ms-works'],
'wdp' => ['image/vnd.ms-photo'],
'web' => ['application/vnd.xara'],
'weba' => ['audio/webm'],
'webapp' =>
['application/x-web-app-manifest+json'],
'webm' => ['video/webm'],
'webp' => ['image/webp'],
'wg' =>
['application/vnd.pmi.widget'],
'wgt' => ['application/widget'],
'wiz' => ['application/msword'],
'wk1' => ['application/x-123'],
'wks' => ['application/vnd.ms-works'],
'wm' => ['video/x-ms-wm'],
'wma' => ['audio/x-ms-wma'],
'wmd' => ['application/x-ms-wmd'],
'wmf' => ['application/x-msmetafile'],
'wml' => ['text/vnd.wap.wml'],
'wmlc' => ['application/vnd.wap.wmlc'],
'wmls' => ['text/vnd.wap.wmlscript'],
'wmlsc' =>
['application/vnd.wap.wmlscriptc'],
'wmv' => ['video/x-ms-wmv'],
'wmx' => ['video/x-ms-wmx'],
'wmz' => ['application/x-msmetafile'],
'woff' => ['application/x-font-woff'],
'word' => ['application/msword'],
'wp' => ['application/wordperfect'],
'wp5' => ['application/wordperfect',
'application/wordperfect6.0'],
'wp6' => ['application/wordperfect'],
'wpd' => ['application/wordperfect',
'application/x-wpwin'],
'wpl' => ['application/vnd.ms-wpl'],
'wps' => ['application/vnd.ms-works'],
'wq1' => ['application/x-lotus'],
'wqd' => ['application/vnd.wqd'],
'wri' => ['application/mswrite',
'application/x-wri'],
'wrl' => ['application/x-world',
'model/vrml', 'x-world/x-vrml'],
'wrz' => ['model/vrml',
'x-world/x-vrml'],
'wsc' => ['text/scriplet'],
'wsdl' => ['application/wsdl+xml'],
'wspolicy' => ['application/wspolicy+xml'],
'wsrc' => ['application/x-wais-source'],
'wtb' => ['application/vnd.webturbo'],
'wtk' => ['application/x-wintalk'],
'wvx' => ['video/x-ms-wvx'],
'x-png' => ['image/png'],
'x32' =>
['application/x-authorware-bin'],
'x3d' => ['model/x3d+xml'],
'x3db' => ['model/x3d+binary'],
'x3dbz' => ['model/x3d+binary'],
'x3dv' => ['model/x3d+vrml'],
'x3dvz' => ['model/x3d+vrml'],
'x3dz' => ['model/x3d+xml'],
'xaml' => ['application/xaml+xml'],
'xap' =>
['application/x-silverlight-app'],
'xar' => ['application/vnd.xara'],
'xbap' => ['application/x-ms-xbap'],
'xbd' =>
['application/vnd.fujixerox.docuworks.binder'],
'xbm' => ['image/x-xbitmap',
'image/x-xbm', 'image/xbm'],
'xdf' => ['application/xcap-diff+xml'],
'xdm' =>
['application/vnd.syncml.dm+xml'],
'xdp' =>
['application/vnd.adobe.xdp+xml'],
'xdr' => ['video/x-amt-demorun'],
'xdssc' => ['application/dssc+xml'],
'xdw' =>
['application/vnd.fujixerox.docuworks'],
'xenc' => ['application/xenc+xml'],
'xer' =>
['application/patch-ops-error+xml'],
'xfdf' =>
['application/vnd.adobe.xfdf'],
'xfdl' => ['application/vnd.xfdl'],
'xgz' => ['xgl/drawing'],
'xht' => ['application/xhtml+xml'],
'xhtml' => ['application/xhtml+xml'],
'xhvml' => ['application/xv+xml'],
'xif' => ['image/vnd.xiff'],
'xl' => ['application/excel'],
'xla' => ['application/excel',
'application/x-excel', 'application/x-msexcel'],
'xlam' =>
['application/vnd.ms-excel.addin.macroenabled.12'],
'xlb' => ['application/excel',
'application/vnd.ms-excel', 'application/x-excel'],
'xlc' => ['application/excel',
'application/vnd.ms-excel', 'application/x-excel'],
'xld' => ['application/excel',
'application/x-excel'],
'xlf' => ['application/x-xliff+xml'],
'xlk' => ['application/excel',
'application/x-excel'],
'xll' => ['application/excel',
'application/vnd.ms-excel', 'application/x-excel'],
'xlm' => ['application/excel',
'application/vnd.ms-excel', 'application/x-excel'],
'xls' => ['application/excel',
'application/vnd.ms-excel', 'application/x-excel',
'application/x-msexcel'],
'xlsb' =>
['application/vnd.ms-excel.sheet.binary.macroenabled.12'],
'xlsm' =>
['application/vnd.ms-excel.sheet.macroenabled.12'],
'xlsx' =>
['application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'],
'xlt' => ['application/excel',
'application/x-excel'],
'xltm' =>
['application/vnd.ms-excel.template.macroenabled.12'],
'xltx' =>
['application/vnd.openxmlformats-officedocument.spreadsheetml.template'],
'xlv' => ['application/excel',
'application/x-excel'],
'xlw' => ['application/excel',
'application/vnd.ms-excel', 'application/x-excel',
'application/x-msexcel'],
'xm' => ['audio/xm'],
'xml' => ['application/xml',
'text/xml'],
'xmz' => ['xgl/movie'],
'xo' =>
['application/vnd.olpc-sugar'],
'xop' => ['application/xop+xml'],
'xpdl' => ['application/xml'],
'xpi' => ['application/x-xpinstall'],
'xpix' => ['application/x-vnd.ls-xpix'],
'xpl' => ['application/xproc+xml'],
'xpm' => ['image/x-xpixmap',
'image/xpm'],
'xpr' => ['application/vnd.is-xpr'],
'xps' =>
['application/vnd.ms-xpsdocument'],
'xpw' =>
['application/vnd.intercon.formnet'],
'xpx' =>
['application/vnd.intercon.formnet'],
'xsl' => ['application/xml'],
'xslt' => ['application/xslt+xml'],
'xsm' =>
['application/vnd.syncml+xml'],
'xspf' => ['application/xspf+xml'],
'xsr' => ['video/x-amt-showrun'],
'xul' =>
['application/vnd.mozilla.xul+xml'],
'xvm' => ['application/xv+xml'],
'xvml' => ['application/xv+xml'],
'xwd' => ['image/x-xwd',
'image/x-xwindowdump'],
'xyz' => ['chemical/x-xyz'],
'xz' => ['application/x-xz'],
'yang' => ['application/yang'],
'yin' => ['application/yin+xml'],
'z' => ['application/x-compress',
'application/x-compressed'],
'z1' => ['application/x-zmachine'],
'z2' => ['application/x-zmachine'],
'z3' => ['application/x-zmachine'],
'z4' => ['application/x-zmachine'],
'z5' => ['application/x-zmachine'],
'z6' => ['application/x-zmachine'],
'z7' => ['application/x-zmachine'],
'z8' => ['application/x-zmachine'],
'zaz' =>
['application/vnd.zzazz.deck+xml'],
'zip' => ['application/x-compressed',
'application/x-zip-compressed', 'application/zip',
'multipart/x-zip'],
'zir' => ['application/vnd.zul'],
'zirz' => ['application/vnd.zul'],
'zmm' =>
['application/vnd.handheld-entertainment+xml'],
'zoo' => ['application/octet-stream'],
'zsh' => ['text/x-script.zsh'],
'123' =>
['application/vnd.lotus-1-2-3'],
];
$fileExt = strtolower(\JFile::getExt($filename));
return isset($mimeTypes[$fileExt]) ? $mimeTypes[$fileExt] :
'application/octet-stream';
}
}BaseController.php000064400000062674151156667020010223 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\Controller;
defined('JPATH_PLATFORM') or die;
/**
* Base class for a Joomla Controller
*
* Controller (Controllers are where you put all the actual code.) Provides
basic
* functionality, such as rendering views (aka displaying templates).
*
* @since 2.5.5
*/
class BaseController extends \JObject
{
/**
* The base path of the controller
*
* @var string
* @since 3.0
*/
protected $basePath;
/**
* The default view for the display method.
*
* @var string
* @since 3.0
*/
protected $default_view;
/**
* The mapped task that was performed.
*
* @var string
* @since 3.0
*/
protected $doTask;
/**
* Redirect message.
*
* @var string
* @since 3.0
*/
protected $message;
/**
* Redirect message type.
*
* @var string
* @since 3.0
*/
protected $messageType;
/**
* Array of class methods
*
* @var array
* @since 3.0
*/
protected $methods;
/**
* The name of the controller
*
* @var array
* @since 3.0
*/
protected $name;
/**
* The prefix of the models
*
* @var string
* @since 3.0
*/
protected $model_prefix;
/**
* The set of search directories for resources (views).
*
* @var array
* @since 3.0
*/
protected $paths;
/**
* URL for redirection.
*
* @var string
* @since 3.0
*/
protected $redirect;
/**
* Current or most recently performed task.
*
* @var string
* @since 3.0
*/
protected $task;
/**
* Array of class methods to call for a given task.
*
* @var array
* @since 3.0
*/
protected $taskMap;
/**
* Hold a JInput object for easier access to the input variables.
*
* @var \JInput
* @since 3.0
*/
protected $input;
/**
* Instance container.
*
* @var \JControllerLegacy
* @since 3.0
*/
protected static $instance;
/**
* Instance container containing the views.
*
* @var \JViewLegacy[]
* @since 3.4
*/
protected static $views;
/**
* Adds to the stack of model paths in LIFO order.
*
* @param mixed $path The directory (string), or list of
directories (array) to add.
* @param string $prefix A prefix for models
*
* @return void
*
* @since 3.0
*/
public static function addModelPath($path, $prefix = '')
{
\JModelLegacy::addIncludePath($path, $prefix);
}
/**
* 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.
Optional.
*
* @return string The filename.
*
* @since 3.0
*/
protected static function createFileName($type, $parts = array())
{
$filename = '';
switch ($type)
{
case 'controller':
if (!empty($parts['format']))
{
if ($parts['format'] === 'html')
{
$parts['format'] = '';
}
else
{
$parts['format'] = '.' .
$parts['format'];
}
}
else
{
$parts['format'] = '';
}
$filename = strtolower($parts['name'] .
$parts['format'] . '.php');
break;
case 'view':
if (!empty($parts['type']))
{
$parts['type'] = '.' . $parts['type'];
}
else
{
$parts['type'] = '';
}
$filename = strtolower($parts['name'] . '/view' .
$parts['type'] . '.php');
break;
}
return $filename;
}
/**
* Method to get a singleton controller instance.
*
* @param string $prefix The prefix for the controller.
* @param array $config An array of optional constructor options.
*
* @return \JControllerLegacy
*
* @since 3.0
* @throws \Exception if the controller cannot be loaded.
*/
public static function getInstance($prefix, $config = array())
{
if (is_object(self::$instance))
{
return self::$instance;
}
$input = \JFactory::getApplication()->input;
// Get the environment configuration.
$basePath = array_key_exists('base_path', $config) ?
$config['base_path'] : JPATH_COMPONENT;
$format = $input->getWord('format');
$command = $input->get('task', 'display');
// Check for array format.
$filter = \JFilterInput::getInstance();
if (is_array($command))
{
$command = $filter->clean(array_pop(array_keys($command)),
'cmd');
}
else
{
$command = $filter->clean($command, 'cmd');
}
// Check for a controller.task command.
if (strpos($command, '.') !== false)
{
// Explode the controller.task command.
list ($type, $task) = explode('.', $command);
// Define the controller filename and path.
$file = self::createFileName('controller',
array('name' => $type, 'format' => $format));
$path = $basePath . '/controllers/' . $file;
$backuppath = $basePath . '/controller/' . $file;
// Reset the task without the controller context.
$input->set('task', $task);
}
else
{
// Base controller.
$type = null;
// Define the controller filename and path.
$file = self::createFileName('controller',
array('name' => 'controller', 'format'
=> $format));
$path = $basePath . '/' . $file;
$backupfile = self::createFileName('controller',
array('name' => 'controller'));
$backuppath = $basePath . '/' . $backupfile;
}
// Get the controller class name.
$class = ucfirst($prefix) . 'Controller' . ucfirst($type);
// Include the class if not present.
if (!class_exists($class))
{
// If the controller file path exists, include it.
if (file_exists($path))
{
require_once $path;
}
elseif (isset($backuppath) && file_exists($backuppath))
{
require_once $backuppath;
}
else
{
throw new
\InvalidArgumentException(\JText::sprintf('JLIB_APPLICATION_ERROR_INVALID_CONTROLLER',
$type, $format));
}
}
// Instantiate the class.
if (!class_exists($class))
{
throw new
\InvalidArgumentException(\JText::sprintf('JLIB_APPLICATION_ERROR_INVALID_CONTROLLER_CLASS',
$class));
}
// Instantiate the class, store it to the static container, and return it
return self::$instance = new $class($config);
}
/**
* Constructor.
*
* @param array $config An optional associative array of configuration
settings.
* Recognized key values include 'name',
'default_task', 'model_path', and
* 'view_path' (this list is not meant to be comprehensive).
*
* @since 3.0
*/
public function __construct($config = array())
{
$this->methods = array();
$this->message = null;
$this->messageType = 'message';
$this->paths = array();
$this->redirect = null;
$this->taskMap = array();
if (defined('JDEBUG') && JDEBUG)
{
\JLog::addLogger(array('text_file' =>
'jcontroller.log.php'), \JLog::ALL,
array('controller'));
}
$this->input = \JFactory::getApplication()->input;
// Determine the methods to exclude from the base class.
$xMethods = get_class_methods('\JControllerLegacy');
// Get the public methods in this class using reflection.
$r = new \ReflectionClass($this);
$rMethods = $r->getMethods(\ReflectionMethod::IS_PUBLIC);
foreach ($rMethods as $rMethod)
{
$mName = $rMethod->getName();
// Add default display method if not explicitly declared.
if ($mName === 'display' || !in_array($mName, $xMethods))
{
$this->methods[] = strtolower($mName);
// Auto register the methods as tasks.
$this->taskMap[strtolower($mName)] = $mName;
}
}
// Set the view name
if (empty($this->name))
{
if (array_key_exists('name', $config))
{
$this->name = $config['name'];
}
else
{
$this->name = $this->getName();
}
}
// Set a base path for use by the controller
if (array_key_exists('base_path', $config))
{
$this->basePath = $config['base_path'];
}
else
{
$this->basePath = JPATH_COMPONENT;
}
// If the default task is set, register it as such
if (array_key_exists('default_task', $config))
{
$this->registerDefaultTask($config['default_task']);
}
else
{
$this->registerDefaultTask('display');
}
// Set the models prefix
if (empty($this->model_prefix))
{
if (array_key_exists('model_prefix', $config))
{
// User-defined prefix
$this->model_prefix = $config['model_prefix'];
}
else
{
$this->model_prefix = ucfirst($this->name) . 'Model';
}
}
// Set the default model search path
if (array_key_exists('model_path', $config))
{
// User-defined dirs
$this->addModelPath($config['model_path'],
$this->model_prefix);
}
else
{
$this->addModelPath($this->basePath . '/models',
$this->model_prefix);
}
// Set the default view search path
if (array_key_exists('view_path', $config))
{
// User-defined dirs
$this->setPath('view', $config['view_path']);
}
else
{
$this->setPath('view', $this->basePath .
'/views');
}
// Set the default view.
if (array_key_exists('default_view', $config))
{
$this->default_view = $config['default_view'];
}
elseif (empty($this->default_view))
{
$this->default_view = $this->getName();
}
}
/**
* Adds to the search path for templates and resources.
*
* @param string $type The path type (e.g. 'model',
'view').
* @param mixed $path The directory string or stream array to
search.
*
* @return \JControllerLegacy A \JControllerLegacy object to support
chaining.
*
* @since 3.0
*/
protected function addPath($type, $path)
{
if (!isset($this->paths[$type]))
{
$this->paths[$type] = array();
}
// Loop through the path directories
foreach ((array) $path as $dir)
{
// No surrounding spaces allowed!
$dir = rtrim(\JPath::check($dir), '/') . '/';
// Add to the top of the search dirs
array_unshift($this->paths[$type], $dir);
}
return $this;
}
/**
* Add one or more view paths to the controller's stack, in LIFO
order.
*
* @param mixed $path The directory (string) or list of directories
(array) to add.
*
* @return \JControllerLegacy This object to support chaining.
*
* @since 3.0
*/
public function addViewPath($path)
{
return $this->addPath('view', $path);
}
/**
* Authorisation check
*
* @param string $task The ACO Section Value to check access on.
*
* @return boolean True if authorised
*
* @since 3.0
* @deprecated 3.0 Use \JAccess instead.
*/
public function authorise($task)
{
\JLog::add(__METHOD__ . ' is deprecated. Use \JAccess
instead.', \JLog::WARNING, 'deprecated');
return true;
}
/**
* Method to check whether an ID is in the edit list.
*
* @param string $context The context for the session storage.
* @param integer $id The ID of the record to add to the edit
list.
*
* @return boolean True if the ID is in the edit list.
*
* @since 3.0
*/
protected function checkEditId($context, $id)
{
if ($id)
{
$values = (array) \JFactory::getApplication()->getUserState($context
. '.id');
$result = in_array((int) $id, $values);
if (defined('JDEBUG') && JDEBUG)
{
\JLog::add(
sprintf(
'Checking edit ID %s.%s: %d %s',
$context,
$id,
(int) $result,
str_replace("\n", ' ', print_r($values, 1))
),
\JLog::INFO,
'controller'
);
}
return $result;
}
// No id for a new item.
return true;
}
/**
* Method to load and return a model object.
*
* @param string $name The name of the model.
* @param string $prefix Optional model prefix.
* @param array $config Configuration array for the model. Optional.
*
* @return \JModelLegacy|boolean Model object on success; otherwise
false on failure.
*
* @since 3.0
*/
protected function createModel($name, $prefix = '', $config =
array())
{
// Clean the model name
$modelName = preg_replace('/[^A-Z0-9_]/i', '',
$name);
$classPrefix = preg_replace('/[^A-Z0-9_]/i', '',
$prefix);
return \JModelLegacy::getInstance($modelName, $classPrefix, $config);
}
/**
* Method to load and return a view object. This method first looks in the
* current template directory for a match and, failing that, uses a
default
* set path to load the view class file.
*
* Note the "name, prefix, type" order of parameters, which
differs from the
* "name, type, prefix" order used in related public methods.
*
* @param string $name The name of the view.
* @param string $prefix Optional prefix for the view class name.
* @param string $type The type of view.
* @param array $config Configuration array for the view. Optional.
*
* @return \JViewLegacy|null View object on success; null or error
result on failure.
*
* @since 3.0
* @throws \Exception
*/
protected function createView($name, $prefix = '', $type =
'', $config = array())
{
// Clean the view name
$viewName = preg_replace('/[^A-Z0-9_]/i', '', $name);
$classPrefix = preg_replace('/[^A-Z0-9_]/i', '',
$prefix);
$viewType = preg_replace('/[^A-Z0-9_]/i', '', $type);
// Build the view class name
$viewClass = $classPrefix . $viewName;
if (!class_exists($viewClass))
{
jimport('joomla.filesystem.path');
$path = \JPath::find($this->paths['view'],
$this->createFileName('view', array('name' =>
$viewName, 'type' => $viewType)));
if (!$path)
{
return null;
}
require_once $path;
if (!class_exists($viewClass))
{
throw new
\Exception(\JText::sprintf('JLIB_APPLICATION_ERROR_VIEW_CLASS_NOT_FOUND',
$viewClass, $path), 500);
}
}
return new $viewClass($config);
}
/**
* Typical view method for MVC based architecture
*
* This function is provide as a default implementation, in most cases
* you will need to override it in your own controllers.
*
* @param boolean $cachable If true, the view output will be cached
* @param array $urlparams An array of safe URL parameters and their
variable types, for valid values see {@link \JFilterInput::clean()}.
*
* @return \JControllerLegacy A \JControllerLegacy object to support
chaining.
*
* @since 3.0
*/
public function display($cachable = false, $urlparams = array())
{
$document = \JFactory::getDocument();
$viewType = $document->getType();
$viewName = $this->input->get('view',
$this->default_view);
$viewLayout = $this->input->get('layout',
'default', 'string');
$view = $this->getView($viewName, $viewType, '',
array('base_path' => $this->basePath, 'layout'
=> $viewLayout));
// Get/Create the model
if ($model = $this->getModel($viewName))
{
// Push the model into the view (as default)
$view->setModel($model, true);
}
$view->document = $document;
// Display the view
if ($cachable && $viewType !== 'feed' &&
\JFactory::getConfig()->get('caching') >= 1)
{
$option = $this->input->get('option');
if (is_array($urlparams))
{
$app = \JFactory::getApplication();
if (!empty($app->registeredurlparams))
{
$registeredurlparams = $app->registeredurlparams;
}
else
{
$registeredurlparams = new \stdClass;
}
foreach ($urlparams as $key => $value)
{
// Add your safe URL parameters with variable type as value {@see
\JFilterInput::clean()}.
$registeredurlparams->$key = $value;
}
$app->registeredurlparams = $registeredurlparams;
}
try
{
/** @var \JCacheControllerView $cache */
$cache = \JFactory::getCache($option, 'view');
$cache->get($view, 'display');
}
catch (\JCacheException $exception)
{
$view->display();
}
}
else
{
$view->display();
}
return $this;
}
/**
* Execute a task by triggering a method in the derived class.
*
* @param string $task The task to perform. If no matching task is
found, the '__default' task is executed, if defined.
*
* @return mixed The value returned by the called method.
*
* @since 3.0
* @throws \Exception
*/
public function execute($task)
{
$this->task = $task;
$task = strtolower($task);
if (isset($this->taskMap[$task]))
{
$doTask = $this->taskMap[$task];
}
elseif (isset($this->taskMap['__default']))
{
$doTask = $this->taskMap['__default'];
}
else
{
throw new
\Exception(\JText::sprintf('JLIB_APPLICATION_ERROR_TASK_NOT_FOUND',
$task), 404);
}
// Record the actual task being fired
$this->doTask = $doTask;
return $this->$doTask();
}
/**
* Method to get a model object, loading it if required.
*
* @param string $name The model name. Optional.
* @param string $prefix The class prefix. Optional.
* @param array $config Configuration array for model. Optional.
*
* @return \JModelLegacy|boolean Model object on success; otherwise
false on failure.
*
* @since 3.0
*/
public function getModel($name = '', $prefix = '',
$config = array())
{
if (empty($name))
{
$name = $this->getName();
}
if (empty($prefix))
{
$prefix = $this->model_prefix;
}
if ($model = $this->createModel($name, $prefix, $config))
{
// Task is a reserved state
$model->setState('task', $this->task);
// Let's get the application object and set menu information if
it's available
$menu = \JFactory::getApplication()->getMenu();
if (is_object($menu) && $item = $menu->getActive())
{
$params = $menu->getParams($item->id);
// Set default state data
$model->setState('parameters.menu', $params);
}
}
return $model;
}
/**
* Method to get the controller name
*
* The dispatcher name is set 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 dispatcher
*
* @since 3.0
* @throws \Exception
*/
public function getName()
{
if (empty($this->name))
{
$r = null;
if (!preg_match('/(.*)Controller/i', get_class($this), $r))
{
throw new
\Exception(\JText::_('JLIB_APPLICATION_ERROR_CONTROLLER_GET_NAME'),
500);
}
$this->name = strtolower($r[1]);
}
return $this->name;
}
/**
* Get the last task that is being performed or was most recently
performed.
*
* @return string The task that is being performed or was most recently
performed.
*
* @since 3.0
*/
public function getTask()
{
return $this->task;
}
/**
* Gets the available tasks in the controller.
*
* @return array Array[i] of task names.
*
* @since 3.0
*/
public function getTasks()
{
return $this->methods;
}
/**
* Method to get a reference to the current view and load it if necessary.
*
* @param string $name The view name. Optional, defaults to the
controller name.
* @param string $type The view type. Optional.
* @param string $prefix The class prefix. Optional.
* @param array $config Configuration array for view. Optional.
*
* @return \JViewLegacy Reference to the view or an error.
*
* @since 3.0
* @throws \Exception
*/
public function getView($name = '', $type = '',
$prefix = '', $config = array())
{
// @note We use self so we only access stuff in this class rather than in
all classes.
if (!isset(self::$views))
{
self::$views = array();
}
if (empty($name))
{
$name = $this->getName();
}
if (empty($prefix))
{
$prefix = $this->getName() . 'View';
}
if (empty(self::$views[$name][$type][$prefix]))
{
if ($view = $this->createView($name, $prefix, $type, $config))
{
self::$views[$name][$type][$prefix] = & $view;
}
else
{
throw new
\Exception(\JText::sprintf('JLIB_APPLICATION_ERROR_VIEW_NOT_FOUND',
$name, $type, $prefix), 404);
}
}
return self::$views[$name][$type][$prefix];
}
/**
* Method to add a record ID to the edit list.
*
* @param string $context The context for the session storage.
* @param integer $id The ID of the record to add to the edit
list.
*
* @return void
*
* @since 3.0
*/
protected function holdEditId($context, $id)
{
$app = \JFactory::getApplication();
$values = (array) $app->getUserState($context . '.id');
// Add the id to the list if non-zero.
if (!empty($id))
{
$values[] = (int) $id;
$values = array_unique($values);
$app->setUserState($context . '.id', $values);
if (defined('JDEBUG') && JDEBUG)
{
\JLog::add(
sprintf(
'Holding edit ID %s.%s %s',
$context,
$id,
str_replace("\n", ' ', print_r($values, 1))
),
\JLog::INFO,
'controller'
);
}
}
}
/**
* Redirects the browser or returns false if no redirect is set.
*
* @return boolean False if no redirect exists.
*
* @since 3.0
*/
public function redirect()
{
if ($this->redirect)
{
$app = \JFactory::getApplication();
// Enqueue the redirect message
$app->enqueueMessage($this->message, $this->messageType);
// Execute the redirect
$app->redirect($this->redirect);
}
return false;
}
/**
* Register the default task to perform if a mapping is not found.
*
* @param string $method The name of the method in the derived class
to perform if a named task is not found.
*
* @return \JControllerLegacy A \JControllerLegacy object to support
chaining.
*
* @since 3.0
*/
public function registerDefaultTask($method)
{
$this->registerTask('__default', $method);
return $this;
}
/**
* Register (map) a task to a method in the class.
*
* @param string $task The task.
* @param string $method The name of the method in the derived class
to perform for this task.
*
* @return \JControllerLegacy A \JControllerLegacy object to support
chaining.
*
* @since 3.0
*/
public function registerTask($task, $method)
{
if (in_array(strtolower($method), $this->methods))
{
$this->taskMap[strtolower($task)] = $method;
}
return $this;
}
/**
* Unregister (unmap) a task in the class.
*
* @param string $task The task.
*
* @return \JControllerLegacy This object to support chaining.
*
* @since 3.0
*/
public function unregisterTask($task)
{
unset($this->taskMap[strtolower($task)]);
return $this;
}
/**
* Method to check whether an ID is in the edit list.
*
* @param string $context The context for the session storage.
* @param integer $id The ID of the record to add to the edit
list.
*
* @return void
*
* @since 3.0
*/
protected function releaseEditId($context, $id)
{
$app = \JFactory::getApplication();
$values = (array) $app->getUserState($context . '.id');
// Do a strict search of the edit list values.
$index = array_search((int) $id, $values, true);
if (is_int($index))
{
unset($values[$index]);
$app->setUserState($context . '.id', $values);
if (defined('JDEBUG') && JDEBUG)
{
\JLog::add(
sprintf(
'Releasing edit ID %s.%s %s',
$context,
$id,
str_replace("\n", ' ', print_r($values, 1))
),
\JLog::INFO,
'controller'
);
}
}
}
/**
* Sets the internal message that is passed with a redirect
*
* @param string $text Message to display on redirect.
* @param string $type Message type. Optional, defaults to
'message'.
*
* @return string Previous message
*
* @since 3.0
*/
public function setMessage($text, $type = 'message')
{
$previous = $this->message;
$this->message = $text;
$this->messageType = $type;
return $previous;
}
/**
* Sets an entire array of search paths for resources.
*
* @param string $type The type of path to set, typically
'view' or 'model'.
* @param string $path The new set of search paths. If null or false,
resets to the current directory only.
*
* @return void
*
* @since 3.0
*/
protected function setPath($type, $path)
{
// Clear out the prior search dirs
$this->paths[$type] = array();
// Actually add the user-specified directories
$this->addPath($type, $path);
}
/**
* Checks for a form token in the request.
*
* Use in conjunction with \JHtml::_('form.token') or
\JSession::getFormToken.
*
* @param string $method The request method in which to look for
the token key.
* @param boolean $redirect Whether to implicitly redirect user to the
referrer page on failure or simply return false.
*
* @return boolean True if found and valid, otherwise return false or
redirect to referrer page.
*
* @since 3.7.0
* @see \JSession::checkToken()
*/
public function checkToken($method = 'post', $redirect = true)
{
$valid = \JSession::checkToken($method);
if (!$valid && $redirect)
{
$referrer =
$this->input->server->getString('HTTP_REFERER');
if (!\JUri::isInternal($referrer))
{
$referrer = 'index.php';
}
$app = \JFactory::getApplication();
$app->enqueueMessage(\JText::_('JINVALID_TOKEN_NOTICE'),
'warning');
$app->redirect($referrer);
}
return $valid;
}
/**
* Set a URL for browser redirection.
*
* @param string $url URL to redirect to.
* @param string $msg Message to display on redirect. Optional,
defaults to value set internally by controller, if any.
* @param string $type Message type. Optional, defaults to
'message' or the type set by a previous call to setMessage.
*
* @return \JControllerLegacy This object to support chaining.
*
* @since 3.0
*/
public function setRedirect($url, $msg = null, $type = null)
{
$this->redirect = $url;
if ($msg !== null)
{
// Controller may have set this directly
$this->message = $msg;
}
// Ensure the type is not overwritten by a previous call to setMessage.
if (empty($type))
{
if (empty($this->messageType))
{
$this->messageType = 'message';
}
}
// If the type is explicitly set, set it.
else
{
$this->messageType = $type;
}
return $this;
}
}
FormController.php000064400000061533151156667020010245 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\Controller;
defined('JPATH_PLATFORM') or die;
/**
* Controller tailored to suit most form-based admin operations.
*
* @since 1.6
* @todo Add ability to set redirect manually to better cope with
frontend usage.
*/
class FormController extends BaseController
{
/**
* The context for storing internal data, e.g. record.
*
* @var string
* @since 1.6
*/
protected $context;
/**
* The URL option for the component.
*
* @var string
* @since 1.6
*/
protected $option;
/**
* The URL view item variable.
*
* @var string
* @since 1.6
*/
protected $view_item;
/**
* The URL view list variable.
*
* @var string
* @since 1.6
*/
protected $view_list;
/**
* The prefix to use with controller messages.
*
* @var string
* @since 1.6
*/
protected $text_prefix;
/**
* Constructor.
*
* @param array $config An optional associative array of configuration
settings.
*
* @see \JControllerLegacy
* @since 1.6
* @throws \Exception
*/
public function __construct($config = array())
{
parent::__construct($config);
// Guess the option as com_NameOfController
if (empty($this->option))
{
$this->option = 'com_' . strtolower($this->getName());
}
// Guess the \JText message prefix. Defaults to the option.
if (empty($this->text_prefix))
{
$this->text_prefix = strtoupper($this->option);
}
// Guess the context as the suffix, eg: OptionControllerContent.
if (empty($this->context))
{
$r = null;
if (!preg_match('/(.*)Controller(.*)/i', get_class($this),
$r))
{
throw new
\Exception(\JText::_('JLIB_APPLICATION_ERROR_CONTROLLER_GET_NAME'),
500);
}
$this->context = strtolower($r[2]);
}
// Guess the item view as the context.
if (empty($this->view_item))
{
$this->view_item = $this->context;
}
// Guess the list view as the plural of the item view.
if (empty($this->view_list))
{
// @TODO Probably worth moving to an inflector class based on
//
http://kuwamoto.org/2007/12/17/improved-pluralizing-in-php-actionscript-and-ror/
// Simple pluralisation based on public domain snippet by Paul Osman
// For more complex types, just manually set the variable in your class.
$plural = array(
array('/(x|ch|ss|sh)$/i', "$1es"),
array('/([^aeiouy]|qu)y$/i', "$1ies"),
array('/([^aeiouy]|qu)ies$/i', "$1y"),
array('/(bu)s$/i', "$1ses"),
array('/s$/i', 's'),
array('/$/', 's'),
);
// Check for matches using regular expressions
foreach ($plural as $pattern)
{
if (preg_match($pattern[0], $this->view_item))
{
$this->view_list = preg_replace($pattern[0], $pattern[1],
$this->view_item);
break;
}
}
}
// Apply, Save & New, and Save As copy should be standard on forms.
$this->registerTask('apply', 'save');
$this->registerTask('save2new', 'save');
$this->registerTask('save2copy', 'save');
$this->registerTask('editAssociations', 'save');
}
/**
* Method to add a new record.
*
* @return boolean True if the record can be added, false if not.
*
* @since 1.6
*/
public function add()
{
$context = "$this->option.edit.$this->context";
// Access check.
if (!$this->allowAdd())
{
// Set the internal error and also the redirect error.
$this->setError(\JText::_('JLIB_APPLICATION_ERROR_CREATE_RECORD_NOT_PERMITTED'));
$this->setMessage($this->getError(), 'error');
$this->setRedirect(
\JRoute::_(
'index.php?option=' . $this->option .
'&view=' . $this->view_list
. $this->getRedirectToListAppend(), false
)
);
return false;
}
// Clear the record edit information from the session.
\JFactory::getApplication()->setUserState($context .
'.data', null);
// Redirect to the edit screen.
$this->setRedirect(
\JRoute::_(
'index.php?option=' . $this->option .
'&view=' . $this->view_item
. $this->getRedirectToItemAppend(), false
)
);
return true;
}
/**
* Method to check if you can add a new record.
*
* Extended classes can override this if necessary.
*
* @param array $data An array of input data.
*
* @return boolean
*
* @since 1.6
*/
protected function allowAdd($data = array())
{
$user = \JFactory::getUser();
return $user->authorise('core.create', $this->option) ||
count($user->getAuthorisedCategories($this->option,
'core.create'));
}
/**
* Method to check if you can edit an existing record.
*
* Extended classes can override this if necessary.
*
* @param array $data An array of input data.
* @param string $key The name of the key for the primary key;
default is id.
*
* @return boolean
*
* @since 1.6
*/
protected function allowEdit($data = array(), $key = 'id')
{
return \JFactory::getUser()->authorise('core.edit',
$this->option);
}
/**
* Method to check if you can save a new or existing record.
*
* Extended classes can override this if necessary.
*
* @param array $data An array of input data.
* @param string $key The name of the key for the primary key.
*
* @return boolean
*
* @since 1.6
*/
protected function allowSave($data, $key = 'id')
{
$recordId = isset($data[$key]) ? $data[$key] : '0';
if ($recordId)
{
return $this->allowEdit($data, $key);
}
else
{
return $this->allowAdd($data);
}
}
/**
* Method to run batch operations.
*
* @param \JModelLegacy $model The model of the component being
processed.
*
* @return boolean True if successful, false otherwise and internal error
is set.
*
* @since 1.7
*/
public function batch($model)
{
$vars = $this->input->post->get('batch', array(),
'array');
$cid = $this->input->post->get('cid', array(),
'array');
// Build an array of item contexts to check
$contexts = array();
$option = isset($this->extension) ? $this->extension :
$this->option;
foreach ($cid as $id)
{
// If we're coming from com_categories, we need to use extension
vs. option
$contexts[$id] = $option . '.' . $this->context .
'.' . $id;
}
// Attempt to run the batch operation.
if ($model->batch($vars, $cid, $contexts))
{
$this->setMessage(\JText::_('JLIB_APPLICATION_SUCCESS_BATCH'));
return true;
}
else
{
$this->setMessage(\JText::sprintf('JLIB_APPLICATION_ERROR_BATCH_FAILED',
$model->getError()), 'warning');
return false;
}
}
/**
* Method to cancel an edit.
*
* @param string $key The name of the primary key of the URL variable.
*
* @return boolean True if access level checks pass, false otherwise.
*
* @since 1.6
*/
public function cancel($key = null)
{
$this->checkToken();
$model = $this->getModel();
$table = $model->getTable();
$context = "$this->option.edit.$this->context";
if (empty($key))
{
$key = $table->getKeyName();
}
$recordId = $this->input->getInt($key);
// Attempt to check-in the current record.
if ($recordId && property_exists($table, 'checked_out')
&& $model->checkin($recordId) === false)
{
// Check-in failed, go back to the record and display a notice.
$this->setError(\JText::sprintf('JLIB_APPLICATION_ERROR_CHECKIN_FAILED',
$model->getError()));
$this->setMessage($this->getError(), 'error');
$this->setRedirect(
\JRoute::_(
'index.php?option=' . $this->option .
'&view=' . $this->view_item
. $this->getRedirectToItemAppend($recordId, $key), false
)
);
return false;
}
// Clean the session data and redirect.
$this->releaseEditId($context, $recordId);
\JFactory::getApplication()->setUserState($context .
'.data', null);
$url = 'index.php?option=' . $this->option .
'&view=' . $this->view_list
. $this->getRedirectToListAppend();
// Check if there is a return value
$return = $this->input->get('return', null,
'base64');
if (!is_null($return) &&
\JUri::isInternal(base64_decode($return)))
{
$url = base64_decode($return);
}
// Redirect to the list screen.
$this->setRedirect(\JRoute::_($url, false));
return true;
}
/**
* Method to edit an existing record.
*
* @param string $key The name of the primary key of the URL
variable.
* @param string $urlVar The name of the URL variable if different
from the primary key
* (sometimes required to avoid router
collisions).
*
* @return boolean True if access level check and checkout passes, false
otherwise.
*
* @since 1.6
*/
public function edit($key = null, $urlVar = null)
{
// Do not cache the response to this, its a redirect, and mod_expires and
google chrome browser bugs cache it forever!
\JFactory::getApplication()->allowCache(false);
$model = $this->getModel();
$table = $model->getTable();
$cid = $this->input->post->get('cid', array(),
'array');
$context = "$this->option.edit.$this->context";
// Determine the name of the primary key for the data.
if (empty($key))
{
$key = $table->getKeyName();
}
// To avoid data collisions the urlVar may be different from the primary
key.
if (empty($urlVar))
{
$urlVar = $key;
}
// Get the previous record id (if any) and the current record id.
$recordId = (int) (count($cid) ? $cid[0] :
$this->input->getInt($urlVar));
$checkin = property_exists($table,
$table->getColumnAlias('checked_out'));
// Access check.
if (!$this->allowEdit(array($key => $recordId), $key))
{
$this->setError(\JText::_('JLIB_APPLICATION_ERROR_EDIT_NOT_PERMITTED'));
$this->setMessage($this->getError(), 'error');
$this->setRedirect(
\JRoute::_(
'index.php?option=' . $this->option .
'&view=' . $this->view_list
. $this->getRedirectToListAppend(), false
)
);
return false;
}
// Attempt to check-out the new record for editing and redirect.
if ($checkin && !$model->checkout($recordId))
{
// Check-out failed, display a notice but allow the user to see the
record.
$this->setError(\JText::sprintf('JLIB_APPLICATION_ERROR_CHECKOUT_FAILED',
$model->getError()));
$this->setMessage($this->getError(), 'error');
$this->setRedirect(
\JRoute::_(
'index.php?option=' . $this->option .
'&view=' . $this->view_item
. $this->getRedirectToItemAppend($recordId, $urlVar), false
)
);
return false;
}
else
{
// Check-out succeeded, push the new record id into the session.
$this->holdEditId($context, $recordId);
\JFactory::getApplication()->setUserState($context .
'.data', null);
$this->setRedirect(
\JRoute::_(
'index.php?option=' . $this->option .
'&view=' . $this->view_item
. $this->getRedirectToItemAppend($recordId, $urlVar), false
)
);
return true;
}
}
/**
* Method to get a model object, loading it if required.
*
* @param string $name The model name. Optional.
* @param string $prefix The class prefix. Optional.
* @param array $config Configuration array for model. Optional.
*
* @return \JModelLegacy The model.
*
* @since 1.6
*/
public function getModel($name = '', $prefix = '',
$config = array('ignore_request' => true))
{
if (empty($name))
{
$name = $this->context;
}
return parent::getModel($name, $prefix, $config);
}
/**
* Gets the URL arguments to append to an item redirect.
*
* @param integer $recordId The primary key id for the item.
* @param string $urlVar The name of the URL variable for the id.
*
* @return string The arguments to append to the redirect URL.
*
* @since 1.6
*/
protected function getRedirectToItemAppend($recordId = null, $urlVar =
'id')
{
$append = '';
// Setup redirect info.
if ($tmpl = $this->input->get('tmpl', '',
'string'))
{
$append .= '&tmpl=' . $tmpl;
}
if ($layout = $this->input->get('layout',
'edit', 'string'))
{
$append .= '&layout=' . $layout;
}
if ($forcedLanguage = $this->input->get('forcedLanguage',
'', 'cmd'))
{
$append .= '&forcedLanguage=' . $forcedLanguage;
}
if ($recordId)
{
$append .= '&' . $urlVar . '=' . $recordId;
}
$return = $this->input->get('return', null,
'base64');
if ($return)
{
$append .= '&return=' . $return;
}
return $append;
}
/**
* Gets the URL arguments to append to a list redirect.
*
* @return string The arguments to append to the redirect URL.
*
* @since 1.6
*/
protected function getRedirectToListAppend()
{
$append = '';
// Setup redirect info.
if ($tmpl = $this->input->get('tmpl', '',
'string'))
{
$append .= '&tmpl=' . $tmpl;
}
if ($forcedLanguage = $this->input->get('forcedLanguage',
'', 'cmd'))
{
$append .= '&forcedLanguage=' . $forcedLanguage;
}
return $append;
}
/**
* Function that allows child controller access to model data
* after the data has been saved.
*
* @param \JModelLegacy $model The data model object.
* @param array $validData The validated data.
*
* @return void
*
* @since 1.6
*/
protected function postSaveHook(\JModelLegacy $model, $validData =
array())
{
}
/**
* Method to load a row from version history
*
* @return mixed True if the record can be added, an error object if
not.
*
* @since 3.2
*/
public function loadhistory()
{
$model = $this->getModel();
$table = $model->getTable();
$historyId = $this->input->getInt('version_id', null);
if (!$model->loadhistory($historyId, $table))
{
$this->setMessage($model->getError(), 'error');
$this->setRedirect(
\JRoute::_(
'index.php?option=' . $this->option .
'&view=' . $this->view_list
. $this->getRedirectToListAppend(), false
)
);
return false;
}
// Determine the name of the primary key for the data.
if (empty($key))
{
$key = $table->getKeyName();
}
$recordId = $table->$key;
// To avoid data collisions the urlVar may be different from the primary
key.
$urlVar = empty($this->urlVar) ? $key : $this->urlVar;
// Access check.
if (!$this->allowEdit(array($key => $recordId), $key))
{
$this->setError(\JText::_('JLIB_APPLICATION_ERROR_EDIT_NOT_PERMITTED'));
$this->setMessage($this->getError(), 'error');
$this->setRedirect(
\JRoute::_(
'index.php?option=' . $this->option .
'&view=' . $this->view_list
. $this->getRedirectToListAppend(), false
)
);
$table->checkin();
return false;
}
$table->store();
$this->setRedirect(
\JRoute::_(
'index.php?option=' . $this->option .
'&view=' . $this->view_item
. $this->getRedirectToItemAppend($recordId, $urlVar), false
)
);
$this->setMessage(
\JText::sprintf(
'JLIB_APPLICATION_SUCCESS_LOAD_HISTORY',
$model->getState('save_date'),
$model->getState('version_note')
)
);
// Invoke the postSave method to allow for the child class to access the
model.
$this->postSaveHook($model);
return true;
}
/**
* Method to save a record.
*
* @param string $key The name of the primary key of the URL
variable.
* @param string $urlVar The name of the URL variable if different
from the primary key (sometimes required to avoid router collisions).
*
* @return boolean True if successful, false otherwise.
*
* @since 1.6
*/
public function save($key = null, $urlVar = null)
{
// Check for request forgeries.
$this->checkToken();
$app = \JFactory::getApplication();
$model = $this->getModel();
$table = $model->getTable();
$data = $this->input->post->get('jform', array(),
'array');
$checkin = property_exists($table,
$table->getColumnAlias('checked_out'));
$context = "$this->option.edit.$this->context";
$task = $this->getTask();
// Determine the name of the primary key for the data.
if (empty($key))
{
$key = $table->getKeyName();
}
// To avoid data collisions the urlVar may be different from the primary
key.
if (empty($urlVar))
{
$urlVar = $key;
}
$recordId = $this->input->getInt($urlVar);
// Populate the row id from the session.
$data[$key] = $recordId;
// The save2copy task needs to be handled slightly differently.
if ($task === 'save2copy')
{
// Check-in the original row.
if ($checkin && $model->checkin($data[$key]) === false)
{
// Check-in failed. Go back to the item and display a notice.
$this->setError(\JText::sprintf('JLIB_APPLICATION_ERROR_CHECKIN_FAILED',
$model->getError()));
$this->setMessage($this->getError(), 'error');
$this->setRedirect(
\JRoute::_(
'index.php?option=' . $this->option .
'&view=' . $this->view_item
. $this->getRedirectToItemAppend($recordId, $urlVar), false
)
);
return false;
}
// Reset the ID, the multilingual associations and then treat the
request as for Apply.
$data[$key] = 0;
$data['associations'] = array();
$task = 'apply';
}
// Access check.
if (!$this->allowSave($data, $key))
{
$this->setError(\JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'));
$this->setMessage($this->getError(), 'error');
$this->setRedirect(
\JRoute::_(
'index.php?option=' . $this->option .
'&view=' . $this->view_list
. $this->getRedirectToListAppend(), false
)
);
return false;
}
// Validate the posted data.
// Sometimes the form needs some posted data, such as for plugins and
modules.
$form = $model->getForm($data, false);
if (!$form)
{
$app->enqueueMessage($model->getError(), 'error');
return false;
}
// Send an object which can be modified through the plugin event
$objData = (object) $data;
$app->triggerEvent(
'onContentNormaliseRequestData',
array($this->option . '.' . $this->context, $objData,
$form)
);
$data = (array) $objData;
// Test whether the data is valid.
$validData = $model->validate($form, $data);
// Check for validation errors.
if ($validData === false)
{
// Get the validation messages.
$errors = $model->getErrors();
// Push up to three validation messages out to the user.
for ($i = 0, $n = count($errors); $i < $n && $i < 3; $i++)
{
if ($errors[$i] instanceof \Exception)
{
$app->enqueueMessage($errors[$i]->getMessage(),
'warning');
}
else
{
$app->enqueueMessage($errors[$i], 'warning');
}
}
/**
* We need the filtered value of calendar fields because the UTC
normalision is
* done in the filter and on output. This would apply the Timezone
offset on
* reload. We set the calendar values we save to the processed date.
*/
$filteredData = $form->filter($data);
foreach ($form->getFieldset() as $field)
{
if ($field->type === 'Calendar')
{
$fieldName = $field->fieldname;
if (isset($filteredData[$fieldName]))
{
$data[$fieldName] = $filteredData[$fieldName];
}
}
}
// Save the data in the session.
$app->setUserState($context . '.data', $data);
// Redirect back to the edit screen.
$this->setRedirect(
\JRoute::_(
'index.php?option=' . $this->option .
'&view=' . $this->view_item
. $this->getRedirectToItemAppend($recordId, $urlVar), false
)
);
return false;
}
if (!isset($validData['tags']))
{
$validData['tags'] = null;
}
// Attempt to save the data.
if (!$model->save($validData))
{
// Save the data in the session.
$app->setUserState($context . '.data', $validData);
// Redirect back to the edit screen.
$this->setError(\JText::sprintf('JLIB_APPLICATION_ERROR_SAVE_FAILED',
$model->getError()));
$this->setMessage($this->getError(), 'error');
$this->setRedirect(
\JRoute::_(
'index.php?option=' . $this->option .
'&view=' . $this->view_item
. $this->getRedirectToItemAppend($recordId, $urlVar), false
)
);
return false;
}
// Save succeeded, so check-in the record.
if ($checkin && $model->checkin($validData[$key]) === false)
{
// Save the data in the session.
$app->setUserState($context . '.data', $validData);
// Check-in failed, so go back to the record and display a notice.
$this->setError(\JText::sprintf('JLIB_APPLICATION_ERROR_CHECKIN_FAILED',
$model->getError()));
$this->setMessage($this->getError(), 'error');
$this->setRedirect(
\JRoute::_(
'index.php?option=' . $this->option .
'&view=' . $this->view_item
. $this->getRedirectToItemAppend($recordId, $urlVar), false
)
);
return false;
}
$langKey = $this->text_prefix . ($recordId === 0 &&
$app->isClient('site') ? '_SUBMIT' : '') .
'_SAVE_SUCCESS';
$prefix = \JFactory::getLanguage()->hasKey($langKey) ?
$this->text_prefix : 'JLIB_APPLICATION';
$this->setMessage(\JText::_($prefix . ($recordId === 0 &&
$app->isClient('site') ? '_SUBMIT' : '') .
'_SAVE_SUCCESS'));
// Redirect the user and adjust session state based on the chosen task.
switch ($task)
{
case 'apply':
// Set the record data in the session.
$recordId = $model->getState($this->context . '.id');
$this->holdEditId($context, $recordId);
$app->setUserState($context . '.data', null);
$model->checkout($recordId);
// Redirect back to the edit screen.
$this->setRedirect(
\JRoute::_(
'index.php?option=' . $this->option .
'&view=' . $this->view_item
. $this->getRedirectToItemAppend($recordId, $urlVar), false
)
);
break;
case 'save2new':
// Clear the record id and data from the session.
$this->releaseEditId($context, $recordId);
$app->setUserState($context . '.data', null);
// Redirect back to the edit screen.
$this->setRedirect(
\JRoute::_(
'index.php?option=' . $this->option .
'&view=' . $this->view_item
. $this->getRedirectToItemAppend(null, $urlVar), false
)
);
break;
default:
// Clear the record id and data from the session.
$this->releaseEditId($context, $recordId);
$app->setUserState($context . '.data', null);
$url = 'index.php?option=' . $this->option .
'&view=' . $this->view_list
. $this->getRedirectToListAppend();
// Check if there is a return value
$return = $this->input->get('return', null,
'base64');
if (!is_null($return) &&
\JUri::isInternal(base64_decode($return)))
{
$url = base64_decode($return);
}
// Redirect to the list screen.
$this->setRedirect(\JRoute::_($url, false));
break;
}
// Invoke the postSave method to allow for the child class to access the
model.
$this->postSaveHook($model, $validData);
return true;
}
/**
* Method to reload a record.
*
* @param string $key The name of the primary key of the URL
variable.
* @param string $urlVar The name of the URL variable if different
from the primary key (sometimes required to avoid router collisions).
*
* @return void
*
* @since 3.7.4
*/
public function reload($key = null, $urlVar = null)
{
// Check for request forgeries.
$this->checkToken();
$app = \JFactory::getApplication();
$model = $this->getModel();
$data = $this->input->post->get('jform', array(),
'array');
// Determine the name of the primary key for the data.
if (empty($key))
{
$key = $model->getTable()->getKeyName();
}
// To avoid data collisions the urlVar may be different from the primary
key.
if (empty($urlVar))
{
$urlVar = $key;
}
$recordId = $this->input->getInt($urlVar);
// Populate the row id from the session.
$data[$key] = $recordId;
// Check if it is allowed to edit or create the data
if (($recordId && !$this->allowEdit($data, $key)) ||
(!$recordId && !$this->allowAdd($data)))
{
$this->setRedirect(
\JRoute::_(
'index.php?option=' . $this->option .
'&view=' . $this->view_list
. $this->getRedirectToListAppend(), false
)
);
$this->redirect();
}
// The redirect url
$redirectUrl = \JRoute::_(
'index.php?option=' . $this->option .
'&view=' . $this->view_item .
$this->getRedirectToItemAppend($recordId, $urlVar),
false
);
/* @var \JForm $form */
$form = $model->getForm($data, false);
/**
* We need the filtered value of calendar fields because the UTC
normalision is
* done in the filter and on output. This would apply the Timezone offset
on
* reload. We set the calendar values we save to the processed date.
*/
$filteredData = $form->filter($data);
foreach ($form->getFieldset() as $field)
{
if ($field->type === 'Calendar')
{
$fieldName = $field->fieldname;
if (isset($filteredData[$fieldName]))
{
$data[$fieldName] = $filteredData[$fieldName];
}
}
}
// Save the data in the session.
$app->setUserState($this->option . '.edit.' .
$this->context . '.data', $data);
$this->setRedirect($redirectUrl);
$this->redirect();
}
/**
* Load item to edit associations in com_associations
*
* @return void
*
* @since 3.9.0
*
* @deprecated 5.0 It is handled by regular save method now.
*/
public function editAssociations()
{
// Initialise variables.
$app = \JFactory::getApplication();
$input = $app->input;
$model = $this->getModel();
$data = $input->get('jform', array(), 'array');
$model->editAssociations($data);
}
}