Spade

Mini Shell

Directory:~$ /home/lmsyaran/public_html/joomla4/
Upload File

[Home] [System Details] [Kill Me]
Current File:~$ /home/lmsyaran/public_html/joomla4/Controller.tar

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);
	}
}