diff --git a/plugins/behaviour/compat/classes/Input/Cookie.php b/plugins/behaviour/compat/classes/Input/Cookie.php new file mode 100644 index 0000000000000..29fd6910b4891 --- /dev/null +++ b/plugins/behaviour/compat/classes/Input/Cookie.php @@ -0,0 +1,159 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace Joomla\CMS\Input; + +use Joomla\CMS\Filter\InputFilter; + +// phpcs:disable PSR1.Files.SideEffects +\defined('_JEXEC') or die; +// phpcs:enable PSR1.Files.SideEffects + +/** + * Joomla! Input Cookie Class + * + * @since 1.7.0 + * + * @deprecated 4.3 will be removed in 6.0. + * Use Joomla\Input\Cookie instead + */ +class Cookie extends Input +{ + /** + * Constructor. + * + * @param array $source Ignored. + * @param array $options Array of configuration parameters (Optional) + * + * @since 1.7.0 + * + * @deprecated 4.3 will be removed in 6.0. + * Use Joomla\Input\Cookie instead + */ + public function __construct(?array $source = null, array $options = []) + { + if (isset($options['filter'])) { + $this->filter = $options['filter']; + } else { + $this->filter = InputFilter::getInstance(); + } + + // Set the data source. + $this->data = &$_COOKIE; + + // Set the options for the class. + $this->options = $options; + } + + /** + * Sets a value + * + * @param string $name Name of the value to set. + * @param mixed $value Value to assign to the input. + * @param array $options An associative array which may have any of the keys expires, path, domain, + * secure, httponly and samesite. The values have the same meaning as described + * for the parameters with the same name. The value of the samesite element + * should be either Lax or Strict. If any of the allowed options are not given, + * their default values are the same as the default values of the explicit + * parameters. If the samesite element is omitted, no SameSite cookie attribute + * is set. + * + * @return void + * + * @link http://www.ietf.org/rfc/rfc2109.txt + * @see setcookie() + * @since 1.7.0 + * + * @deprecated 4.3 will be removed in 6.0. + * Use Joomla\Input\Cookie instead + */ + public function set($name, $value, $options = []) + { + // BC layer to convert old method parameters. + if (\is_array($options) === false) { + trigger_deprecation( + 'joomla/input', + '1.4.0', + 'The %s($name, $value, $expire, $path, $domain, $secure, $httpOnly) signature is deprecated and' + . ' will not be supported once support' + . ' for PHP 7.2 and earlier is dropped, use the %s($name, $value, $options) signature instead', + __METHOD__, + __METHOD__ + ); + + $argList = \func_get_args(); + + $options = [ + 'expires' => $argList[2] ?? 0, + 'path' => $argList[3] ?? '', + 'domain' => $argList[4] ?? '', + 'secure' => $argList[5] ?? false, + 'httponly' => $argList[6] ?? false, + ]; + } + + // Set the cookie + if (version_compare(PHP_VERSION, '7.3', '>=')) { + if (\is_array($value)) { + foreach ($value as $key => $val) { + setcookie($name . "[$key]", $val, $options); + } + } else { + setcookie($name, $value, $options); + } + } else { + // Using the setcookie function before php 7.3, make sure we have default values. + if (\array_key_exists('expires', $options) === false) { + $options['expires'] = 0; + } + + if (\array_key_exists('path', $options) === false) { + $options['path'] = ''; + } + + if (\array_key_exists('domain', $options) === false) { + $options['domain'] = ''; + } + + if (\array_key_exists('secure', $options) === false) { + $options['secure'] = false; + } + + if (\array_key_exists('httponly', $options) === false) { + $options['httponly'] = false; + } + + if (\is_array($value)) { + foreach ($value as $key => $val) { + setcookie( + $name . "[$key]", + $val, + $options['expires'], + $options['path'], + $options['domain'], + $options['secure'], + $options['httponly'] + ); + } + } else { + setcookie( + $name, + $value, + $options['expires'], + $options['path'], + $options['domain'], + $options['secure'], + $options['httponly'] + ); + } + } + + $this->data[$name] = $value; + } +} diff --git a/plugins/behaviour/compat/classes/Input/Files.php b/plugins/behaviour/compat/classes/Input/Files.php new file mode 100644 index 0000000000000..7839946e88ab3 --- /dev/null +++ b/plugins/behaviour/compat/classes/Input/Files.php @@ -0,0 +1,152 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace Joomla\CMS\Input; + +use Joomla\CMS\Filter\InputFilter; + +// phpcs:disable PSR1.Files.SideEffects +\defined('_JEXEC') or die; +// phpcs:enable PSR1.Files.SideEffects + +/** + * Joomla! Input Files Class + * + * @since 1.7.0 + * + * @deprecated 4.3 will be removed in 6.0. + * Use Joomla\Input\Files instead + */ +class Files extends Input +{ + /** + * The pivoted data from a $_FILES or compatible array. + * + * @var array + * @since 1.7.0 + * + * @deprecated 4.3 will be removed in 6.0. + * Use Joomla\Input\Files instead + */ + protected $decodedData = []; + + /** + * The class constructor. + * + * @param array $source The source argument is ignored. $_FILES is always used. + * @param array $options An optional array of configuration options: + * filter : a custom InputFilter object. + * + * @since 3.0.0 + * + * @deprecated 4.3 will be removed in 6.0. + * Use Joomla\Input\Files instead + */ + public function __construct(?array $source = null, array $options = []) + { + if (isset($options['filter'])) { + $this->filter = $options['filter']; + } else { + $this->filter = InputFilter::getInstance(); + } + + // Set the data source. + $this->data = &$_FILES; + + // Set the options for the class. + $this->options = $options; + } + + /** + * Gets a value from the input data. + * + * @param string $name The name of the input property (usually the name of the files INPUT tag) to get. + * @param mixed $default The default value to return if the named property does not exist. + * @param string $filter The filter to apply to the value. + * + * @return mixed The filtered input value. + * + * @see InputFilter::clean() + * @since 1.7.0 + * + * @deprecated 4.3 will be removed in 6.0. + * Use Joomla\Input\Files instead + */ + public function get($name, $default = null, $filter = 'cmd') + { + if (isset($this->data[$name])) { + $results = $this->decodeData( + [ + $this->data[$name]['name'], + $this->data[$name]['type'], + $this->data[$name]['tmp_name'], + $this->data[$name]['error'], + $this->data[$name]['size'], + ] + ); + + // Prevent returning an unsafe file unless specifically requested + if (strtoupper($filter) !== 'RAW') { + $isSafe = InputFilter::isSafeFile($results); + + if (!$isSafe) { + return $default; + } + } + + return $results; + } + + return $default; + } + + /** + * Method to decode a data array. + * + * @param array $data The data array to decode. + * + * @return array + * + * @since 1.7.0 + * + * @deprecated 4.3 will be removed in 6.0. + * Use Joomla\Input\Files instead + */ + protected function decodeData(array $data) + { + $result = []; + + if (\is_array($data[0])) { + foreach ($data[0] as $k => $v) { + $result[$k] = $this->decodeData([$data[0][$k], $data[1][$k], $data[2][$k], $data[3][$k], $data[4][$k]]); + } + + return $result; + } + + return ['name' => $data[0], 'type' => $data[1], 'tmp_name' => $data[2], 'error' => $data[3], 'size' => $data[4]]; + } + + /** + * Sets a value. + * + * @param string $name The name of the input property to set. + * @param mixed $value The value to assign to the input property. + * + * @return void + * + * @since 1.7.0 + * + * @deprecated 4.3 will be removed in 6.0. + * Use Joomla\Input\Files instead + */ + public function set($name, $value) + { + } +} diff --git a/plugins/behaviour/compat/classes/Input/Input.php b/plugins/behaviour/compat/classes/Input/Input.php new file mode 100644 index 0000000000000..e3f5544d32ae5 --- /dev/null +++ b/plugins/behaviour/compat/classes/Input/Input.php @@ -0,0 +1,222 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace Joomla\CMS\Input; + +use Joomla\CMS\Filter\InputFilter; + +// phpcs:disable PSR1.Files.SideEffects +\defined('_JEXEC') or die; +// phpcs:enable PSR1.Files.SideEffects + +/** + * Joomla! Input Base Class + * + * This is an abstracted input class used to manage retrieving data from the application environment. + * + * @since 1.7.0 + * + * @deprecated 4.3 will be removed in 6.0. + * Use Joomla\Input\Input instead + * + * @property-read Input $get + * @property-read Input $post + * @property-read Input $request + * @property-read Input $server + * @property-read Input $env + * @property-read Files $files + * @property-read Cookie $cookie + * @property-read Json $json + */ +class Input extends \Joomla\Input\Input +{ + /** + * Container with allowed superglobals + * + * @var array + * @since 3.8.9 + * + * @deprecated 4.3 will be removed in 6.0. + * Use Joomla\Input\Input instead + */ + private static $allowedGlobals = ['REQUEST', 'GET', 'POST', 'FILES', 'SERVER', 'ENV']; + + /** + * Input objects + * + * @var Input[] + * @since 1.7.0 + * + * @deprecated 4.3 will be removed in 6.0. + * Use Joomla\Input\Input instead + */ + protected $inputs = []; + + /** + * Constructor. + * + * @param array $source Source data (Optional, default is $_REQUEST) + * @param array $options Array of configuration parameters (Optional) + * + * @since 1.7.0 + * + * @deprecated 4.3 will be removed in 6.0. + * Use Joomla\Input\Input instead + */ + public function __construct($source = null, array $options = []) + { + if (!isset($options['filter'])) { + $this->filter = InputFilter::getInstance(); + } + + parent::__construct($source, $options); + } + + /** + * Magic method to get an input object + * + * @param mixed $name Name of the input object to retrieve. + * + * @return \Joomla\Input\Input The request input object + * + * @since 1.7.0 + * + * @deprecated 4.3 will be removed in 6.0. + * Use Joomla\Input\Input instead + */ + public function __get($name) + { + if (isset($this->inputs[$name])) { + return $this->inputs[$name]; + } + + $className = '\\Joomla\\CMS\\Input\\' . ucfirst($name); + + if (class_exists($className)) { + $this->inputs[$name] = new $className(null, $this->options); + + return $this->inputs[$name]; + } + + $superGlobal = '_' . strtoupper($name); + + if (\in_array(strtoupper($name), self::$allowedGlobals, true) && isset($GLOBALS[$superGlobal])) { + $this->inputs[$name] = new Input($GLOBALS[$superGlobal], $this->options); + + return $this->inputs[$name]; + } + + // Try using the parent class + return parent::__get($name); + } + + /** + * Gets an array of values from the request. + * + * @param array $vars Associative array of keys and filter types to apply. + * If empty and datasource is null, all the input data will be returned + * but filtered using the filter given by the parameter defaultFilter in + * InputFilter::clean. + * @param mixed $datasource Array to retrieve data from, or null. + * @param string $defaultFilter Default filter used in InputFilter::clean if vars is empty and + * datasource is null. If 'unknown', the default case is used in + * InputFilter::clean. + * + * @return mixed The filtered input data. + * + * @since 1.7.0 + * + * @deprecated 4.3 will be removed in 6.0. + * Use Joomla\Input\Input instead + */ + public function getArray(array $vars = [], $datasource = null, $defaultFilter = 'unknown') + { + return $this->getArrayRecursive($vars, $datasource, $defaultFilter, false); + } + + /** + * Gets an array of values from the request. + * + * @param array $vars Associative array of keys and filter types to apply. + * If empty and datasource is null, all the input data will be returned + * but filtered using the filter given by the parameter defaultFilter in + * InputFilter::clean. + * @param mixed $datasource Array to retrieve data from, or null. + * @param string $defaultFilter Default filter used in InputFilter::clean if vars is empty and + * datasource is null. If 'unknown', the default case is used in + * InputFilter::clean. + * @param bool $recursion Flag to indicate a recursive function call. + * + * @return mixed The filtered input data. + * + * @since 3.4.2 + * + * @deprecated 4.3 will be removed in 6.0. + * Use Joomla\Input\Input instead + */ + protected function getArrayRecursive(array $vars = [], $datasource = null, $defaultFilter = 'unknown', $recursion = false) + { + if (empty($vars) && \is_null($datasource)) { + $vars = $this->data; + } else { + if (!$recursion) { + $defaultFilter = null; + } + } + + $results = []; + + foreach ($vars as $k => $v) { + if (\is_array($v)) { + if (\is_null($datasource)) { + $results[$k] = $this->getArrayRecursive($v, $this->get($k, null, 'array'), $defaultFilter, true); + } else { + $results[$k] = $this->getArrayRecursive($v, $datasource[$k], $defaultFilter, true); + } + } else { + $filter = $defaultFilter ?? $v; + + if (\is_null($datasource)) { + $results[$k] = $this->get($k, null, $filter); + } elseif (isset($datasource[$k])) { + $results[$k] = $this->filter->clean($datasource[$k], $filter); + } else { + $results[$k] = $this->filter->clean(null, $filter); + } + } + } + + return $results; + } + + /** + * Method to unserialize the input. + * + * @param string $input The serialized input. + * + * @return void + * + * @since 3.0.0 + * + * @deprecated 4.3 will be removed in 6.0. + * Use Joomla\Input\Input instead + */ + public function unserialize($input) + { + // Unserialize the options, data, and inputs. + list($this->options, $this->data, $this->inputs) = unserialize($input); + + // Load the filter. + if (isset($this->options['filter'])) { + $this->filter = $this->options['filter']; + } else { + $this->filter = InputFilter::getInstance(); + } + } +} diff --git a/plugins/behaviour/compat/classes/Input/Json.php b/plugins/behaviour/compat/classes/Input/Json.php new file mode 100644 index 0000000000000..756d392b00e96 --- /dev/null +++ b/plugins/behaviour/compat/classes/Input/Json.php @@ -0,0 +1,88 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace Joomla\CMS\Input; + +use Joomla\CMS\Filter\InputFilter; + +// phpcs:disable PSR1.Files.SideEffects +\defined('_JEXEC') or die; +// phpcs:enable PSR1.Files.SideEffects + +/** + * Joomla! Input JSON Class + * + * This class decodes a JSON string from the raw request data and makes it available via + * the standard JInput interface. + * + * @since 3.0.1 + * + * @deprecated 4.3 will be removed in 6.0. + * Use Joomla\Input\Json instead + */ +class Json extends Input +{ + /** + * @var string The raw JSON string from the request. + * @since 3.0.1 + * + * @deprecated 4.3 will be removed in 6.0. + * Use Joomla\Input\Json instead + */ + // phpcs:ignore + private $_raw; + + /** + * Constructor. + * + * @param array $source Source data (Optional, default is the raw HTTP input decoded from JSON) + * @param array $options Array of configuration parameters (Optional) + * + * @since 3.0.1 + * + * @deprecated 4.3 will be removed in 6.0. + * Use Joomla\Input\Json instead + */ + public function __construct(?array $source = null, array $options = []) + { + if (isset($options['filter'])) { + $this->filter = $options['filter']; + } else { + $this->filter = InputFilter::getInstance(); + } + + if (\is_null($source)) { + $this->_raw = file_get_contents('php://input'); + $this->data = json_decode($this->_raw, true); + + if (!\is_array($this->data)) { + $this->data = []; + } + } else { + $this->data = &$source; + } + + $this->options = $options; + } + + /** + * Gets the raw JSON string from the request. + * + * @return string The raw JSON string from the request. + * + * @since 3.0.1 + * + * @deprecated 4.3 will be removed in 6.0. + * Use Joomla\Input\Json instead + */ + public function getRaw() + { + return $this->_raw; + } +} diff --git a/plugins/behaviour/compat/src/Extension/Compat.php b/plugins/behaviour/compat/src/Extension/Compat.php index ceecc2d2e6547..9c1ea8d3b531c 100644 --- a/plugins/behaviour/compat/src/Extension/Compat.php +++ b/plugins/behaviour/compat/src/Extension/Compat.php @@ -80,6 +80,11 @@ public function __construct(DispatcherInterface $dispatcher, array $config = []) * @deprecated 4.4.0 will be removed in 7.0 */ \defined('JPATH_PLATFORM') or \define('JPATH_PLATFORM', __DIR__); + + /** + * Include classes which are removed in 7.0 + */ + \JLoader::registerNamespace('\\Joomla\\CMS\\Input', JPATH_PLUGINS . '/behaviour/compat/classes/Input'); } /** diff --git a/plugins/behaviour/compat/src/classmap/classmap.php b/plugins/behaviour/compat/src/classmap/classmap.php index c61b068b606d5..f46d916d1a727 100644 --- a/plugins/behaviour/compat/src/classmap/classmap.php +++ b/plugins/behaviour/compat/src/classmap/classmap.php @@ -514,6 +514,3 @@ JLoader::registerAlias('JHtmlTag', '\\Joomla\\CMS\\HTML\\Helpers\\Tag', '6.0'); JLoader::registerAlias('JHtmlTel', '\\Joomla\\CMS\\HTML\\Helpers\\Telephone', '6.0'); JLoader::registerAlias('JHtmlUser', '\\Joomla\\CMS\\HTML\\Helpers\\User', '6.0'); - -// As JLoader is not managing the \Joomla\Input namespace, we need to use the native class alias function -class_alias('\\Joomla\\Input\\Input', '\\Joomla\\CMS\\Input\\Input');