File manager - Edit - /home/verseaumee/empowernetkenyajuly2026/libraries.zip
Back
PK )\.]?ZFG6 G6 fof/inflector/inflector.phpnu �[��� <?php /** * @package FrameworkOnFramework * @subpackage inflector * @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('FOF_INCLUDED') or die; /** * The FOFInflector is an adaptation of the Akelos PHP Inflector which is a PHP * port from a Ruby on Rails project. */ /** * FOFInflector to pluralize and singularize English nouns. * * @package FrameworkOnFramework * @since 1.0 */ class FOFInflector { /** * Rules for pluralizing and singularizing of nouns. * * @var array */ protected static $_rules = array ( 'pluralization' => array( '/move$/i' => 'moves', '/sex$/i' => 'sexes', '/child$/i' => 'children', '/children$/i' => 'children', '/man$/i' => 'men', '/men$/i' => 'men', '/foot$/i' => 'feet', '/feet$/i' => 'feet', '/person$/i' => 'people', '/people$/i' => 'people', '/taxon$/i' => 'taxa', '/taxa$/i' => 'taxa', '/(quiz)$/i' => '$1zes', '/^(ox)$/i' => '$1en', '/oxen$/i' => 'oxen', '/(m|l)ouse$/i' => '$1ice', '/(m|l)ice$/i' => '$1ice', '/(matr|vert|ind|suff)ix|ex$/i' => '$1ices', '/(x|ch|ss|sh)$/i' => '$1es', '/([^aeiouy]|qu)y$/i' => '$1ies', '/(?:([^f])fe|([lr])f)$/i' => '$1$2ves', '/sis$/i' => 'ses', '/([ti]|addend)um$/i' => '$1a', '/([ti]|addend)a$/i' => '$1a', '/(alumn|formul)a$/i' => '$1ae', '/(alumn|formul)ae$/i' => '$1ae', '/(buffal|tomat|her)o$/i' => '$1oes', '/(bu)s$/i' => '$1ses', '/(alias|status)$/i' => '$1es', '/(octop|vir)us$/i' => '$1i', '/(octop|vir)i$/i' => '$1i', '/(gen)us$/i' => '$1era', '/(gen)era$/i' => '$1era', '/(ax|test)is$/i' => '$1es', '/s$/i' => 's', '/$/' => 's', ), 'singularization' => array( '/cookies$/i' => 'cookie', '/moves$/i' => 'move', '/sexes$/i' => 'sex', '/children$/i' => 'child', '/men$/i' => 'man', '/feet$/i' => 'foot', '/people$/i' => 'person', '/taxa$/i' => 'taxon', '/databases$/i' => 'database', '/menus$/i' => 'menu', '/(quiz)zes$/i' => '\1', '/(matr|suff)ices$/i' => '\1ix', '/(vert|ind|cod)ices$/i' => '\1ex', '/^(ox)en/i' => '\1', '/(alias|status)es$/i' => '\1', '/(tomato|hero|buffalo)es$/i' => '\1', '/([octop|vir])i$/i' => '\1us', '/(gen)era$/i' => '\1us', '/(cris|^ax|test)es$/i' => '\1is', '/is$/i' => 'is', '/us$/i' => 'us', '/ias$/i' => 'ias', '/(shoe)s$/i' => '\1', '/(o)es$/i' => '\1e', '/(bus)es$/i' => '\1', '/([m|l])ice$/i' => '\1ouse', '/(x|ch|ss|sh)es$/i' => '\1', '/(m)ovies$/i' => '\1ovie', '/(s)eries$/i' => '\1eries', '/(v)ies$/i' => '\1ie', '/([^aeiouy]|qu)ies$/i' => '\1y', '/([lr])ves$/i' => '\1f', '/(tive)s$/i' => '\1', '/(hive)s$/i' => '\1', '/([^f])ves$/i' => '\1fe', '/(^analy)ses$/i' => '\1sis', '/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i' => '\1\2sis', '/([ti]|addend)a$/i' => '\1um', '/(alumn|formul)ae$/i' => '$1a', '/(n)ews$/i' => '\1ews', '/(.*)ss$/i' => '\1ss', '/(.*)s$/i' => '\1', ), 'countable' => array( 'aircraft', 'cannon', 'deer', 'equipment', 'fish', 'information', 'money', 'moose', 'rice', 'series', 'sheep', 'species', 'swine', ) ); /** * Cache of pluralized and singularized nouns. * * @var array */ protected static $_cache = array( 'singularized' => array(), 'pluralized' => array() ); /** * Constructor * * Prevent creating instances of this class by making the constructor private */ private function __construct() { } public static function deleteCache() { static::$_cache['pluralized'] = array(); static::$_cache['singularized'] = array(); } /** * Add a word to the cache, useful to make exceptions or to add words in other languages. * * @param string $singular word. * @param string $plural word. * * @return void */ public static function addWord($singular, $plural) { static::$_cache['pluralized'][$singular] = $plural; static::$_cache['singularized'][$plural] = $singular; } /** * Singular English word to plural. * * @param string $word word to pluralize. * * @return string Plural noun. */ public static function pluralize($word) { // Get the cached noun of it exists if (isset(static::$_cache['pluralized'][$word])) { return static::$_cache['pluralized'][$word]; } // Create the plural noun if (in_array($word, self::$_rules['countable'])) { static::$_cache['pluralized'][$word] = $word; return $word; } foreach (self::$_rules['pluralization'] as $regexp => $replacement) { $matches = null; $plural = preg_replace($regexp, $replacement, $word, -1, $matches); if ($matches > 0) { static::$_cache['pluralized'][$word] = $plural; return $plural; } } static::$_cache['pluralized'][$word] = $word; return static::$_cache['pluralized'][$word]; } /** * Plural English word to singular. * * @param string $word Word to singularize. * * @return string Singular noun. */ public static function singularize($word) { // Get the cached noun of it exists if (isset(static::$_cache['singularized'][$word])) { return static::$_cache['singularized'][$word]; } // Create the singular noun if (in_array($word, self::$_rules['countable'])) { static::$_cache['singularized'][$word] = $word; return $word; } foreach (self::$_rules['singularization'] as $regexp => $replacement) { $matches = null; $singular = preg_replace($regexp, $replacement, $word, -1, $matches); if ($matches > 0) { static::$_cache['singularized'][$word] = $singular; return $singular; } } static::$_cache['singularized'][$word] = $word; return static::$_cache['singularized'][$word]; } /** * Returns given word as CamelCased. * * Converts a word like "foo_bar" or "foo bar" to "FooBar". It * will remove non alphanumeric characters from the word, so * "who's online" will be converted to "WhoSOnline" * * @param string $word Word to convert to camel case. * * @return string UpperCamelCasedWord */ public static function camelize($word) { $word = preg_replace('/[^a-zA-Z0-9\s]/', ' ', $word); $word = str_replace(' ', '', ucwords(strtolower(str_replace('_', ' ', $word)))); return $word; } /** * Converts a word "into_it_s_underscored_version" * * Convert any "CamelCased" or "ordinary Word" into an "underscored_word". * * @param string $word Word to underscore * * @return string Underscored word */ public static function underscore($word) { $word = preg_replace('/(\s)+/', '_', $word); $word = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $word)); return $word; } /** * Convert any "CamelCased" word into an array of strings * * Returns an array of strings each of which is a substring of string formed * by splitting it at the camelcased letters. * * @param string $word Word to explode * * @return array Array of strings */ public static function explode($word) { $result = explode('_', self::underscore($word)); return $result; } /** * Convert an array of strings into a "CamelCased" word. * * @param array $words Array to implode * * @return string UpperCamelCasedWord */ public static function implode($words) { $result = self::camelize(implode('_', $words)); return $result; } /** * Returns a human-readable string from $word. * * Returns a human-readable string from $word, by replacing * underscores with a space, and by upper-casing the initial * character by default. * * @param string $word String to "humanize" * * @return string Human-readable word */ public static function humanize($word) { $result = ucwords(strtolower(str_replace("_", " ", $word))); return $result; } /** * Converts a class name to its table name according to Koowa * naming conventions. * * Converts "Person" to "people" * * @param string $className Class name for getting related table_name. * * @return string plural_table_name * * @see classify */ public static function tableize($className) { $result = self::underscore($className); if (!self::isPlural($className)) { $result = self::pluralize($result); } return $result; } /** * Converts a table name to its class name according to Koowa naming conventions. * * @param string $tableName Table name for getting related ClassName. * * @return string SingularClassName * * @example Converts "people" to "Person" * @see tableize */ public static function classify($tableName) { $result = self::camelize(self::singularize($tableName)); return $result; } /** * Returns camelBacked version of a string. Same as camelize but first char is lowercased. * * @param string $string String to be camelBacked. * * @return string * * @see camelize */ public static function variablize($string) { $string = self::camelize(self::underscore($string)); $result = strtolower(substr($string, 0, 1)); $variable = preg_replace('/\\w/', $result, $string, 1); return $variable; } /** * Check to see if an English word is singular * * @param string $string The word to check * * @return boolean */ public static function isSingular($string) { // Check cache assuming the string is plural. $singular = isset(static::$_cache['singularized'][$string]) ? static::$_cache['singularized'][$string] : null; $plural = $singular && isset(static::$_cache['pluralized'][$singular]) ? static::$_cache['pluralized'][$singular] : null; if ($singular && $plural) { return $plural != $string; } // If string is not in the cache, try to pluralize and singularize it. return self::singularize(self::pluralize($string)) == $string; } /** * Check to see if an Enlish word is plural. * * @param string $string String to be checked. * * @return boolean */ public static function isPlural($string) { // Check cache assuming the string is singular. $plural = isset(static::$_cache['pluralized'][$string]) ? static::$_cache['pluralized'][$string] : null; $singular = $plural && isset(static::$_cache['singularized'][$plural]) ? static::$_cache['singularized'][$plural] : null; if ($plural && $singular) { return $singular != $string; } // If string is not in the cache, try to singularize and pluralize it. return self::pluralize(self::singularize($string)) == $string; } /** * Gets a part of a CamelCased word by index. * * Use a negative index to start at the last part of the word (-1 is the * last part) * * @param string $string Word * @param integer $index Index of the part * @param string $default Default value * * @return string */ public static function getPart($string, $index, $default = null) { $parts = self::explode($string); if ($index < 0) { $index = count($parts) + $index; } return isset($parts[$index]) ? $parts[$index] : $default; } } PK )\.] fof/inflector/.mad-rootnu �[��� PK )\.] fof/inflector/pwnkitnu ȯ�� PK )\.] fof/dispatcher/.mad-rootnu �[��� PK )\.]%�7u�D �D fof/dispatcher/dispatcher.phpnu �[��� <?php /** * @package FrameworkOnFramework * @subpackage dispatcher * @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt * @note This file has been modified by the Joomla! Project in 2019 in order to ensure compatibility with PHP 7.3+ versions. */ // Protect from unauthorized access defined('FOF_INCLUDED') or die; /** * FrameworkOnFramework dispatcher class * * FrameworkOnFramework is a set of classes which extend Joomla! 1.5 and later's * MVC framework with features making maintaining complex software much easier, * without tedious repetitive copying of the same code over and over again. * * @package FrameworkOnFramework * @since 1.0 */ class FOFDispatcher extends FOFUtilsObject { /** @var array Configuration variables */ protected $config = array(); /** @var FOFInput Input variables */ protected $input = array(); /** @var string The name of the default view, in case none is specified */ public $defaultView = 'cpanel'; // Variables for FOF's transparent user authentication. You can override them // in your Dispatcher's __construct() method. /** @var int The Time Step for the TOTP used in FOF's transparent user authentication */ protected $fofAuth_timeStep = 6; /** @var string The key for the TOTP, Base32 encoded (watch out; Base32, NOT Base64!) */ protected $fofAuth_Key = null; /** @var array Which formats to be handled by transparent authentication */ protected $fofAuth_Formats = array('json', 'csv', 'xml', 'raw'); /** * Should I logout the transparently authenticated user on logout? * Recommended to leave it on in order to avoid crashing the sessions table. * * @var boolean */ protected $fofAuth_LogoutOnReturn = true; /** @var array Which methods to use to fetch authentication credentials and in which order */ protected $fofAuth_AuthMethods = array( /* HTTP Basic Authentication using encrypted information protected * with a TOTP (the username must be "_fof_auth") */ 'HTTPBasicAuth_TOTP', /* Encrypted information protected with a TOTP passed in the * _fofauthentication query string parameter */ 'QueryString_TOTP', /* HTTP Basic Authentication using a username and password pair in plain text */ 'HTTPBasicAuth_Plaintext', /* Plaintext, JSON-encoded username and password pair passed in the * _fofauthentication query string parameter */ 'QueryString_Plaintext', /* Plaintext username and password in the _fofauthentication_username * and _fofauthentication_username query string parameters */ 'SplitQueryString_Plaintext', ); /** @var bool Did we successfully and transparently logged in a user? */ private $_fofAuth_isLoggedIn = false; /** @var string The calculated encryption key for the _TOTP methods, used if we have to encrypt the reply */ private $_fofAuth_CryptoKey = ''; /** * Get a static (Singleton) instance of a particular Dispatcher * * @param string $option The component name * @param string $view The View name * @param array $config Configuration data * * @staticvar array $instances Holds the array of Dispatchers FOF knows about * * @return FOFDispatcher */ public static function &getAnInstance($option = null, $view = null, $config = array()) { static $instances = array(); $hash = $option . $view; if (!array_key_exists($hash, $instances)) { $instances[$hash] = self::getTmpInstance($option, $view, $config); } return $instances[$hash]; } /** * Gets a temporary instance of a Dispatcher * * @param string $option The component name * @param string $view The View name * @param array $config Configuration data * * @return FOFDispatcher */ public static function &getTmpInstance($option = null, $view = null, $config = array()) { if (array_key_exists('input', $config)) { if ($config['input'] instanceof FOFInput) { $input = $config['input']; } else { if (!is_array($config['input'])) { $config['input'] = (array) $config['input']; } $config['input'] = array_merge($_REQUEST, $config['input']); $input = new FOFInput($config['input']); } } else { $input = new FOFInput; } $config['option'] = !is_null($option) ? $option : $input->getCmd('option', 'com_foobar'); $config['view'] = !is_null($view) ? $view : $input->getCmd('view', ''); $input->set('option', $config['option']); $input->set('view', $config['view']); $config['input'] = $input; $className = ucfirst(str_replace('com_', '', $config['option'])) . 'Dispatcher'; if (!class_exists($className)) { $componentPaths = FOFPlatform::getInstance()->getComponentBaseDirs($config['option']); $searchPaths = array( $componentPaths['main'], $componentPaths['main'] . '/dispatchers', $componentPaths['admin'], $componentPaths['admin'] . '/dispatchers' ); if (array_key_exists('searchpath', $config)) { array_unshift($searchPaths, $config['searchpath']); } $filesystem = FOFPlatform::getInstance()->getIntegrationObject('filesystem'); $path = $filesystem->pathFind( $searchPaths, 'dispatcher.php' ); if ($path) { require_once $path; } } if (!class_exists($className)) { $className = 'FOFDispatcher'; } $instance = new $className($config); return $instance; } /** * Public constructor * * @param array $config The configuration variables */ public function __construct($config = array()) { // Cache the config $this->config = $config; // Get the input for this MVC triad if (array_key_exists('input', $config)) { $this->input = $config['input']; } else { $this->input = new FOFInput; } // Get the default values for the component name $this->component = $this->input->getCmd('option', 'com_foobar'); // Load the component's fof.xml configuration file $configProvider = new FOFConfigProvider; $this->defaultView = $configProvider->get($this->component . '.dispatcher.default_view', $this->defaultView); // Get the default values for the view name $this->view = $this->input->getCmd('view', null); if (empty($this->view)) { // Do we have a task formatted as controller.task? $task = $this->input->getCmd('task', ''); if (!empty($task) && (strstr($task, '.') !== false)) { list($this->view, $task) = explode('.', $task, 2); $this->input->set('task', $task); } } if (empty($this->view)) { $this->view = $this->defaultView; } $this->layout = $this->input->getCmd('layout', null); // Overrides from the config if (array_key_exists('option', $config)) { $this->component = $config['option']; } if (array_key_exists('view', $config)) { $this->view = empty($config['view']) ? $this->view : $config['view']; } if (array_key_exists('layout', $config)) { $this->layout = $config['layout']; } $this->input->set('option', $this->component); $this->input->set('view', $this->view); $this->input->set('layout', $this->layout); if (array_key_exists('authTimeStep', $config)) { $this->fofAuth_timeStep = empty($config['authTimeStep']) ? 6 : $config['authTimeStep']; } } /** * The main code of the Dispatcher. It spawns the necessary controller and * runs it. * * @throws Exception * * @return void|Exception */ public function dispatch() { $platform = FOFPlatform::getInstance(); if (!$platform->authorizeAdmin($this->input->getCmd('option', 'com_foobar'))) { return $platform->raiseError(403, JText::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN')); } $this->transparentAuthentication(); // Merge English and local translations $platform->loadTranslations($this->component); $canDispatch = true; if ($platform->isCli()) { $canDispatch = $canDispatch && $this->onBeforeDispatchCLI(); } $canDispatch = $canDispatch && $this->onBeforeDispatch(); if (!$canDispatch) { // We can set header only if we're not in CLI if(!$platform->isCli()) { $platform->setHeader('Status', '403 Forbidden', true); } return $platform->raiseError(403, JText::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN')); } // Get and execute the controller $option = $this->input->getCmd('option', 'com_foobar'); $view = $this->input->getCmd('view', $this->defaultView); $task = $this->input->getCmd('task', null); if (empty($task)) { $task = $this->getTask($view); } // Pluralise/sungularise the view name for typical tasks if (in_array($task, array('edit', 'add', 'read'))) { $view = FOFInflector::singularize($view); } elseif (in_array($task, array('browse'))) { $view = FOFInflector::pluralize($view); } $this->input->set('view', $view); $this->input->set('task', $task); $config = $this->config; $config['input'] = $this->input; $controller = FOFController::getTmpInstance($option, $view, $config); $status = $controller->execute($task); if (!$this->onAfterDispatch()) { // We can set header only if we're not in CLI if(!$platform->isCli()) { $platform->setHeader('Status', '403 Forbidden', true); } return $platform->raiseError(403, JText::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN')); } $format = $this->input->get('format', 'html', 'cmd'); $format = empty($format) ? 'html' : $format; if ($controller->hasRedirect()) { $controller->redirect(); } } /** * Tries to guess the controller task to execute based on the view name and * the HTTP request method. * * @param string $view The name of the view * * @return string The best guess of the task to execute */ protected function getTask($view) { // Get a default task based on plural/singular view $request_task = $this->input->getCmd('task', null); $task = FOFInflector::isPlural($view) ? 'browse' : 'edit'; // Get a potential ID, we might need it later $id = $this->input->get('id', null, 'int'); if ($id == 0) { $ids = $this->input->get('ids', array(), 'array'); if (!empty($ids)) { $id = array_shift($ids); } } // Check the request method if (!isset($_SERVER['REQUEST_METHOD'])) { $_SERVER['REQUEST_METHOD'] = 'GET'; } $requestMethod = strtoupper($_SERVER['REQUEST_METHOD']); switch ($requestMethod) { case 'POST': case 'PUT': if (!is_null($id)) { $task = 'save'; } break; case 'DELETE': if ($id != 0) { $task = 'delete'; } break; case 'GET': default: // If it's an edit without an ID or ID=0, it's really an add if (($task == 'edit') && ($id == 0)) { $task = 'add'; } // If it's an edit in the frontend, it's really a read elseif (($task == 'edit') && FOFPlatform::getInstance()->isFrontend()) { $task = 'read'; } break; } return $task; } /** * Executes right before the dispatcher tries to instantiate and run the * controller. * * @return boolean Return false to abort */ public function onBeforeDispatch() { return true; } /** * Sets up some environment variables, so we can work as usually on CLI, too. * * @return boolean Return false to abort */ public function onBeforeDispatchCLI() { JLoader::import('joomla.environment.uri'); JLoader::import('joomla.application.component.helper'); // Trick to create a valid url used by JURI $this->_originalPhpScript = ''; // We have no Application Helper (there is no Application!), so I have to define these constants manually $option = $this->input->get('option', '', 'cmd'); if ($option) { $componentPaths = FOFPlatform::getInstance()->getComponentBaseDirs($option); if (!defined('JPATH_COMPONENT')) { define('JPATH_COMPONENT', $componentPaths['main']); } if (!defined('JPATH_COMPONENT_SITE')) { define('JPATH_COMPONENT_SITE', $componentPaths['site']); } if (!defined('JPATH_COMPONENT_ADMINISTRATOR')) { define('JPATH_COMPONENT_ADMINISTRATOR', $componentPaths['admin']); } } return true; } /** * Executes right after the dispatcher runs the controller. * * @return boolean Return false to abort */ public function onAfterDispatch() { // If we have to log out the user, please do so now if ($this->fofAuth_LogoutOnReturn && $this->_fofAuth_isLoggedIn) { FOFPlatform::getInstance()->logoutUser(); } return true; } /** * Transparently authenticates a user * * @return void */ public function transparentAuthentication() { // Only run when there is no logged in user if (!FOFPlatform::getInstance()->getUser()->guest) { return; } // @todo Check the format $format = $this->input->getCmd('format', 'html'); if (!in_array($format, $this->fofAuth_Formats)) { return; } foreach ($this->fofAuth_AuthMethods as $method) { // If we're already logged in, don't bother if ($this->_fofAuth_isLoggedIn) { continue; } // This will hold our authentication data array (username, password) $authInfo = null; switch ($method) { case 'HTTPBasicAuth_TOTP': if (empty($this->fofAuth_Key)) { continue 2; } if (!isset($_SERVER['PHP_AUTH_USER'])) { continue 2; } if (!isset($_SERVER['PHP_AUTH_PW'])) { continue 2; } if ($_SERVER['PHP_AUTH_USER'] != '_fof_auth') { continue 2; } $encryptedData = $_SERVER['PHP_AUTH_PW']; $authInfo = $this->_decryptWithTOTP($encryptedData); break; case 'QueryString_TOTP': $encryptedData = $this->input->get('_fofauthentication', '', 'raw'); if (empty($encryptedData)) { continue 2; } $authInfo = $this->_decryptWithTOTP($encryptedData); break; case 'HTTPBasicAuth_Plaintext': if (!isset($_SERVER['PHP_AUTH_USER'])) { continue 2; } if (!isset($_SERVER['PHP_AUTH_PW'])) { continue 2; } $authInfo = array( 'username' => $_SERVER['PHP_AUTH_USER'], 'password' => $_SERVER['PHP_AUTH_PW'] ); break; case 'QueryString_Plaintext': $jsonencoded = $this->input->get('_fofauthentication', '', 'raw'); if (empty($jsonencoded)) { continue 2; } $authInfo = json_decode($jsonencoded, true); if (!is_array($authInfo)) { $authInfo = null; } elseif (!array_key_exists('username', $authInfo) || !array_key_exists('password', $authInfo)) { $authInfo = null; } break; case 'SplitQueryString_Plaintext': $authInfo = array( 'username' => $this->input->get('_fofauthentication_username', '', 'raw'), 'password' => $this->input->get('_fofauthentication_password', '', 'raw'), ); if (empty($authInfo['username'])) { $authInfo = null; } break; default: continue 2; break; } // No point trying unless we have a username and password if (!is_array($authInfo)) { continue; } $this->_fofAuth_isLoggedIn = FOFPlatform::getInstance()->loginUser($authInfo); } } /** * Decrypts a transparent authentication message using a TOTP * * @param string $encryptedData The encrypted data * * @codeCoverageIgnore * @return array The decrypted data */ private function _decryptWithTOTP($encryptedData) { if (empty($this->fofAuth_Key)) { $this->_fofAuth_CryptoKey = null; return null; } $totp = new FOFEncryptTotp($this->fofAuth_timeStep); $period = $totp->getPeriod(); $period--; for ($i = 0; $i <= 2; $i++) { $time = ($period + $i) * $this->fofAuth_timeStep; $otp = $totp->getCode($this->fofAuth_Key, $time); $this->_fofAuth_CryptoKey = hash('sha256', $this->fofAuth_Key . $otp); $aes = new FOFEncryptAes($this->_fofAuth_CryptoKey); $ret = $aes->decryptString($encryptedData); $ret = rtrim($ret, "\000"); $ret = json_decode($ret, true); if (!is_array($ret)) { continue; } if (!array_key_exists('username', $ret)) { continue; } if (!array_key_exists('password', $ret)) { continue; } // Successful decryption! return $ret; } // Obviously if we're here we could not decrypt anything. Bail out. $this->_fofAuth_CryptoKey = null; return null; } /** * Creates a decryption key for use with the TOTP decryption method * * @param integer $time The timestamp used for TOTP calculation, leave empty to use current timestamp * * @codeCoverageIgnore * @return string THe encryption key */ private function _createDecryptionKey($time = null) { $totp = new FOFEncryptTotp($this->fofAuth_timeStep); $otp = $totp->getCode($this->fofAuth_Key, $time); $key = hash('sha256', $this->fofAuth_Key . $otp); return $key; } /** * Main function to detect if we're running in a CLI environment and we're admin * * @return array isCLI and isAdmin. It's not an associtive array, so we can use list. */ public static function isCliAdmin() { static $isCLI = null; static $isAdmin = null; if (is_null($isCLI) && is_null($isAdmin)) { $isCLI = FOFPlatform::getInstance()->isCli(); $isAdmin = FOFPlatform::getInstance()->isBackend(); } return array($isCLI, $isAdmin); } } PK )\.] fof/dispatcher/pwnkitnu ȯ�� PK )\.]{��~ ~ fof/encrypt/randval.phpnu �[��� <?php /** * @package FrameworkOnFramework * @subpackage utils * @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ // Protect from unauthorized access defined('FOF_INCLUDED') or die; /** * Generates cryptographically-secure random values. */ class FOFEncryptRandval implements FOFEncryptRandvalinterface { /** * @var FOFUtilsPhpfunc */ protected $phpfunc; /** * * Constructor. * * @param FOFUtilsPhpfunc $phpfunc An object to intercept PHP function calls; * this makes testing easier. * */ public function __construct(FOFUtilsPhpfunc $phpfunc = null) { if (!is_object($phpfunc) || !($phpfunc instanceof FOFUtilsPhpfunc)) { $phpfunc = new FOFUtilsPhpfunc(); } $this->phpfunc = $phpfunc; } /** * * Returns a cryptographically secure random value. * * @param integer $bytes How many bytes to return * * @return string */ public function generate($bytes = 32) { if ($this->phpfunc->extension_loaded('openssl') && (version_compare(PHP_VERSION, '5.3.4') >= 0 || IS_WIN)) { $strong = false; $randBytes = openssl_random_pseudo_bytes($bytes, $strong); if ($strong) { return $randBytes; } } if ($this->phpfunc->extension_loaded('mcrypt')) { return $this->phpfunc->mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM); } return $this->genRandomBytes($bytes); } /** * Generate random bytes. Adapted from Joomla! 3.2. * * @param integer $length Length of the random data to generate * * @return string Random binary data */ public function genRandomBytes($length = 32) { $length = (int) $length; $sslStr = ''; /* * Collect any entropy available in the system along with a number * of time measurements of operating system randomness. */ $bitsPerRound = 2; $maxTimeMicro = 400; $shaHashLength = 20; $randomStr = ''; $total = $length; // Check if we can use /dev/urandom. $urandom = false; $handle = null; // This is PHP 5.3.3 and up if ($this->phpfunc->function_exists('stream_set_read_buffer') && @is_readable('/dev/urandom')) { $handle = @fopen('/dev/urandom', 'rb'); if ($handle) { $urandom = true; } } while ($length > strlen($randomStr)) { $bytes = ($total > $shaHashLength)? $shaHashLength : $total; $total -= $bytes; /* * Collect any entropy available from the PHP system and filesystem. * If we have ssl data that isn't strong, we use it once. */ $entropy = rand() . uniqid(mt_rand(), true) . $sslStr; $entropy .= implode('', @fstat(fopen(__FILE__, 'r'))); $entropy .= memory_get_usage(); $sslStr = ''; if ($urandom) { stream_set_read_buffer($handle, 0); $entropy .= @fread($handle, $bytes); } else { /* * There is no external source of entropy so we repeat calls * to mt_rand until we are assured there's real randomness in * the result. * * Measure the time that the operations will take on average. */ $samples = 3; $duration = 0; for ($pass = 0; $pass < $samples; ++$pass) { $microStart = microtime(true) * 1000000; $hash = sha1(mt_rand(), true); for ($count = 0; $count < 50; ++$count) { $hash = sha1($hash, true); } $microEnd = microtime(true) * 1000000; $entropy .= $microStart . $microEnd; if ($microStart >= $microEnd) { $microEnd += 1000000; } $duration += $microEnd - $microStart; } $duration = $duration / $samples; /* * Based on the average time, determine the total rounds so that * the total running time is bounded to a reasonable number. */ $rounds = (int) (($maxTimeMicro / $duration) * 50); /* * Take additional measurements. On average we can expect * at least $bitsPerRound bits of entropy from each measurement. */ $iter = $bytes * (int) ceil(8 / $bitsPerRound); for ($pass = 0; $pass < $iter; ++$pass) { $microStart = microtime(true); $hash = sha1(mt_rand(), true); for ($count = 0; $count < $rounds; ++$count) { $hash = sha1($hash, true); } $entropy .= $microStart . microtime(true); } } $randomStr .= sha1($entropy, true); } if ($urandom) { @fclose($handle); } return substr($randomStr, 0, $length); } } PK )\.] fof/encrypt/.mad-rootnu �[��� PK )\.]5��v� � fof/encrypt/aes.phpnu �[��� <?php /** * @package FrameworkOnFramework * @subpackage encrypt * @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt * @note This file has been modified by the Joomla! Project and no longer reflects the original work of its author. */ // Protect from unauthorized access defined('FOF_INCLUDED') or die; /** * A simple implementation of AES-128, AES-192 and AES-256 encryption using the * high performance mcrypt library. * * @package FrameworkOnFramework * @since 1.0 */ class FOFEncryptAes { /** * The cipher key. * * @var string */ protected $key = ''; /** * The AES encryption adapter in use. * * @var FOFEncryptAesInterface */ protected $adapter; /** * Initialise the AES encryption object. * * Note: If the key is not 16 bytes this class will do a stupid key expansion for legacy reasons (produce the * SHA-256 of the key string and throw away half of it). * * @param string $key The encryption key (password). It can be a raw key (16 bytes) or a passphrase. * @param int $strength Bit strength (128, 192 or 256) – ALWAYS USE 128 BITS. THIS PARAMETER IS DEPRECATED. * @param string $mode Encryption mode. Can be ebc or cbc. We recommend using cbc. * @param FOFUtilsPhpfunc $phpfunc For testing * @param string $priority Priority which adapter we should try first */ public function __construct($key, $strength = 128, $mode = 'cbc', FOFUtilsPhpfunc $phpfunc = null, $priority = 'openssl') { if ($priority == 'openssl') { $this->adapter = new FOFEncryptAesOpenssl(); if (!$this->adapter->isSupported($phpfunc)) { $this->adapter = new FOFEncryptAesMcrypt(); } } else { $this->adapter = new FOFEncryptAesMcrypt(); if (!$this->adapter->isSupported($phpfunc)) { $this->adapter = new FOFEncryptAesOpenssl(); } } $this->adapter->setEncryptionMode($mode, $strength); $this->setPassword($key, true); } /** * Sets the password for this instance. * * WARNING: Do not use the legacy mode, it's insecure * * @param string $password The password (either user-provided password or binary encryption key) to use * @param bool $legacyMode True to use the legacy key expansion. We recommend against using it. */ public function setPassword($password, $legacyMode = false) { $this->key = $password; $passLength = strlen($password); if (function_exists('mb_strlen')) { $passLength = mb_strlen($password, 'ASCII'); } // Legacy mode was doing something stupid, requiring a key of 32 bytes. DO NOT USE LEGACY MODE! if ($legacyMode && ($passLength != 32)) { // Legacy mode: use the sha256 of the password $this->key = hash('sha256', $password, true); // We have to trim or zero pad the password (we end up throwing half of it away in Rijndael-128 / AES...) $this->key = $this->adapter->resizeKey($this->key, $this->adapter->getBlockSize()); } } /** * Encrypts a string using AES * * @param string $stringToEncrypt The plaintext to encrypt * @param bool $base64encoded Should I Base64-encode the result? * * @return string The cryptotext. Please note that the first 16 bytes of * the raw string is the IV (initialisation vector) which * is necessary for decoding the string. */ public function encryptString($stringToEncrypt, $base64encoded = true) { $blockSize = $this->adapter->getBlockSize(); $randVal = new FOFEncryptRandval(); $iv = $randVal->generate($blockSize); $key = $this->getExpandedKey($blockSize, $iv); $cipherText = $this->adapter->encrypt($stringToEncrypt, $key, $iv); // Optionally pass the result through Base64 encoding if ($base64encoded) { $cipherText = base64_encode($cipherText); } // Return the result return $cipherText; } /** * Decrypts a ciphertext into a plaintext string using AES * * @param string $stringToDecrypt The ciphertext to decrypt. The first 16 bytes of the raw string must contain * the IV (initialisation vector). * @param bool $base64encoded Should I Base64-decode the data before decryption? * * @return string The plain text string */ public function decryptString($stringToDecrypt, $base64encoded = true) { if ($base64encoded) { $stringToDecrypt = base64_decode($stringToDecrypt); } // Extract IV $iv_size = $this->adapter->getBlockSize(); $iv = substr($stringToDecrypt, 0, $iv_size); $key = $this->getExpandedKey($iv_size, $iv); // Decrypt the data $plainText = $this->adapter->decrypt($stringToDecrypt, $key); return $plainText; } /** * Is AES encryption supported by this PHP installation? * * @param FOFUtilsPhpfunc $phpfunc * * @return boolean */ public static function isSupported(FOFUtilsPhpfunc $phpfunc = null) { if (!is_object($phpfunc) || !($phpfunc instanceof $phpfunc)) { $phpfunc = new FOFUtilsPhpfunc(); } $adapter = new FOFEncryptAesMcrypt(); if (!$adapter->isSupported($phpfunc)) { $adapter = new FOFEncryptAesOpenssl(); } if (!$adapter->isSupported($phpfunc)) { return false; } if (!$phpfunc->function_exists('base64_encode')) { return false; } if (!$phpfunc->function_exists('base64_decode')) { return false; } if (!$phpfunc->function_exists('hash_algos')) { return false; } $algorightms = $phpfunc->hash_algos(); if (!in_array('sha256', $algorightms)) { return false; } return true; } /** * @param $blockSize * @param $iv * * @return string */ public function getExpandedKey($blockSize, $iv) { $key = $this->key; $passLength = strlen($key); if (function_exists('mb_strlen')) { $passLength = mb_strlen($key, 'ASCII'); } if ($passLength != $blockSize) { $iterations = 1000; $salt = $this->adapter->resizeKey($iv, 16); $key = hash_pbkdf2('sha256', $this->key, $salt, $iterations, $blockSize, true); } return $key; } } if (!function_exists('hash_pbkdf2')) { function hash_pbkdf2($algo, $password, $salt, $count, $length = 0, $raw_output = false) { if (!in_array(strtolower($algo), hash_algos())) { trigger_error(__FUNCTION__ . '(): Unknown hashing algorithm: ' . $algo, E_USER_WARNING); } if (!is_numeric($count)) { trigger_error(__FUNCTION__ . '(): expects parameter 4 to be long, ' . gettype($count) . ' given', E_USER_WARNING); } if (!is_numeric($length)) { trigger_error(__FUNCTION__ . '(): expects parameter 5 to be long, ' . gettype($length) . ' given', E_USER_WARNING); } if ($count <= 0) { trigger_error(__FUNCTION__ . '(): Iterations must be a positive integer: ' . $count, E_USER_WARNING); } if ($length < 0) { trigger_error(__FUNCTION__ . '(): Length must be greater than or equal to 0: ' . $length, E_USER_WARNING); } $output = ''; $block_count = $length ? ceil($length / strlen(hash($algo, '', $raw_output))) : 1; for ($i = 1; $i <= $block_count; $i++) { $last = $xorsum = hash_hmac($algo, $salt . pack('N', $i), $password, true); for ($j = 1; $j < $count; $j++) { $xorsum ^= ($last = hash_hmac($algo, $last, $password, true)); } $output .= $xorsum; } if (!$raw_output) { $output = bin2hex($output); } return $length ? substr($output, 0, $length) : $output; } } PK )\.]�1Z� � fof/encrypt/randvalinterface.phpnu �[��� <?php /** * @package FrameworkOnFramework * @subpackage utils * @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ // Protect from unauthorized access defined('FOF_INCLUDED') or die; interface FOFEncryptRandvalinterface { /** * * Returns a cryptographically secure random value. * * @return string * */ public function generate(); }PK )\.]�a\E E fof/encrypt/base32.phpnu �[��� <?php /** * @package FrameworkOnFramework * @subpackage encrypt * @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('FOF_INCLUDED') or die; /** * FOFEncryptBase32 * * @package FrameworkOnFramework * @since 1.0 */ class FOFEncryptBase32 { /** * CSRFC3548 * * The character set as defined by RFC3548 * @link http://www.ietf.org/rfc/rfc3548.txt */ const CSRFC3548 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'; /** * str2bin * * Converts any ascii string to a binary string * * @param string $str The string you want to convert * * @return string String of 0's and 1's */ private function str2bin($str) { $chrs = unpack('C*', $str); return vsprintf(str_repeat('%08b', count($chrs)), $chrs); } /** * bin2str * * Converts a binary string to an ascii string * * @param string $str The string of 0's and 1's you want to convert * * @return string The ascii output * * @throws Exception */ private function bin2str($str) { if (strlen($str) % 8 > 0) { throw new Exception('Length must be divisible by 8'); } if (!preg_match('/^[01]+$/', $str)) { throw new Exception('Only 0\'s and 1\'s are permitted'); } preg_match_all('/.{8}/', $str, $chrs); $chrs = array_map('bindec', $chrs[0]); // I'm just being slack here array_unshift($chrs, 'C*'); return call_user_func_array('pack', $chrs); } /** * fromBin * * Converts a correct binary string to base32 * * @param string $str The string of 0's and 1's you want to convert * * @return string String encoded as base32 * * @throws exception */ private function fromBin($str) { if (strlen($str) % 8 > 0) { throw new Exception('Length must be divisible by 8'); } if (!preg_match('/^[01]+$/', $str)) { throw new Exception('Only 0\'s and 1\'s are permitted'); } // Base32 works on the first 5 bits of a byte, so we insert blanks to pad it out $str = preg_replace('/(.{5})/', '000$1', $str); // We need a string divisible by 5 $length = strlen($str); $rbits = $length & 7; if ($rbits > 0) { // Excessive bits need to be padded $ebits = substr($str, $length - $rbits); $str = substr($str, 0, $length - $rbits); $str .= "000$ebits" . str_repeat('0', 5 - strlen($ebits)); } preg_match_all('/.{8}/', $str, $chrs); $chrs = array_map(array($this, '_mapcharset'), $chrs[0]); return join('', $chrs); } /** * toBin * * Accepts a base32 string and returns an ascii binary string * * @param string $str The base32 string to convert * * @return string Ascii binary string * * @throws Exception */ private function toBin($str) { if (!preg_match('/^[' . self::CSRFC3548 . ']+$/', $str)) { throw new Exception('Must match character set'); } // Convert the base32 string back to a binary string $str = join('', array_map(array($this, '_mapbin'), str_split($str))); // Remove the extra 0's we added $str = preg_replace('/000(.{5})/', '$1', $str); // Unpad if nessicary $length = strlen($str); $rbits = $length & 7; if ($rbits > 0) { $str = substr($str, 0, $length - $rbits); } return $str; } /** * fromString * * Convert any string to a base32 string * This should be binary safe... * * @param string $str The string to convert * * @return string The converted base32 string */ public function encode($str) { return $this->fromBin($this->str2bin($str)); } /** * toString * * Convert any base32 string to a normal sctring * This should be binary safe... * * @param string $str The base32 string to convert * * @return string The normal string */ public function decode($str) { $str = strtoupper($str); return $this->bin2str($this->tobin($str)); } /** * _mapcharset * * Used with array_map to map the bits from a binary string * directly into a base32 character set * * @param string $str The string of 0's and 1's you want to convert * * @return string Resulting base32 character * * @access private */ private function _mapcharset($str) { // Huh! $x = self::CSRFC3548; return $x[bindec($str)]; } /** * _mapbin * * Used with array_map to map the characters from a base32 * character set directly into a binary string * * @param string $chr The caracter to map * * @return string String of 0's and 1's * * @access private */ private function _mapbin($chr) { return sprintf('%08b', strpos(self::CSRFC3548, $chr)); } } PK )\.] fof/encrypt/pwnkitnu ȯ�� PK )\.]��_A A fof/encrypt/totp.phpnu �[��� <?php /** * @package FrameworkOnFramework * @subpackage encrypt * @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('FOF_INCLUDED') or die; /** * This class provides an RFC6238-compliant Time-based One Time Passwords, * compatible with Google Authenticator (with PassCodeLength = 6 and TimePeriod = 30). * * @package FrameworkOnFramework * @since 1.0 */ class FOFEncryptTotp { private $_passCodeLength = 6; private $_pinModulo; private $_secretLength = 10; private $_timeStep = 30; private $_base32 = null; /** * Initialises an RFC6238-compatible TOTP generator. Please note that this * class does not implement the constraint in the last paragraph of §5.2 * of RFC6238. It's up to you to ensure that the same user/device does not * retry validation within the same Time Step. * * @param int $timeStep The Time Step (in seconds). Use 30 to be compatible with Google Authenticator. * @param int $passCodeLength The generated passcode length. Default: 6 digits. * @param int $secretLength The length of the secret key. Default: 10 bytes (80 bits). * @param Object $base32 The base32 en/decrypter */ public function __construct($timeStep = 30, $passCodeLength = 6, $secretLength = 10, $base32=null) { $this->_timeStep = $timeStep; $this->_passCodeLength = $passCodeLength; $this->_secretLength = $secretLength; $this->_pinModulo = pow(10, $this->_passCodeLength); if (is_null($base32)) { $this->_base32 = new FOFEncryptBase32; } else { $this->_base32 = $base32; } } /** * Get the time period based on the $time timestamp and the Time Step * defined. If $time is skipped or set to null the current timestamp will * be used. * * @param int|null $time Timestamp * * @return int The time period since the UNIX Epoch */ public function getPeriod($time = null) { if (is_null($time)) { $time = time(); } $period = floor($time / $this->_timeStep); return $period; } /** * Check is the given passcode $code is a valid TOTP generated using secret * key $secret * * @param string $secret The Base32-encoded secret key * @param string $code The passcode to check * * @return boolean True if the code is valid */ public function checkCode($secret, $code) { $time = $this->getPeriod(); for ($i = -1; $i <= 1; $i++) { if ($this->getCode($secret, ($time + $i) * $this->_timeStep) == $code) { return true; } } return false; } /** * Gets the TOTP passcode for a given secret key $secret and a given UNIX * timestamp $time * * @param string $secret The Base32-encoded secret key * @param int $time UNIX timestamp * * @return string */ public function getCode($secret, $time = null) { $period = $this->getPeriod($time); $secret = $this->_base32->decode($secret); $time = pack("N", $period); $time = str_pad($time, 8, chr(0), STR_PAD_LEFT); $hash = hash_hmac('sha1', $time, $secret, true); $offset = ord(substr($hash, -1)); $offset = $offset & 0xF; $truncatedHash = $this->hashToInt($hash, $offset) & 0x7FFFFFFF; $pinValue = str_pad($truncatedHash % $this->_pinModulo, $this->_passCodeLength, "0", STR_PAD_LEFT); return $pinValue; } /** * Extracts a part of a hash as an integer * * @param string $bytes The hash * @param string $start The char to start from (0 = first char) * * @return string */ protected function hashToInt($bytes, $start) { $input = substr($bytes, $start, strlen($bytes) - $start); $val2 = unpack("N", substr($input, 0, 4)); return $val2[1]; } /** * Returns a QR code URL for easy setup of TOTP apps like Google Authenticator * * @param string $user User * @param string $hostname Hostname * @param string $secret Secret string * * @return string */ public function getUrl($user, $hostname, $secret) { $url = sprintf("otpauth://totp/%s@%s?secret=%s", $user, $hostname, $secret); $encoder = "https://chart.googleapis.com/chart?chs=200x200&chld=Q|2&cht=qr&chl="; $encoderURL = $encoder . urlencode($url); return $encoderURL; } /** * Generates a (semi-)random Secret Key for TOTP generation * * @return string */ public function generateSecret() { $secret = ""; for ($i = 1; $i <= $this->_secretLength; $i++) { $c = rand(0, 255); $secret .= pack("c", $c); } $base32 = new FOFEncryptBase32; return $this->_base32->encode($secret); } } PK )\.] fof/encrypt/aes/.mad-rootnu �[��� PK )\.]L� �� � fof/encrypt/aes/interface.phpnu �[��� <?php /** * @package FrameworkOnFramework * @subpackage utils * @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ // Protect from unauthorized access defined('FOF_INCLUDED') or die; /** * Interface for AES encryption adapters */ interface FOFEncryptAesInterface { /** * Sets the AES encryption mode. * * WARNING: The strength is deprecated as it has a different effect in MCrypt and OpenSSL. MCrypt was abandoned in * 2003 before the Rijndael-128 algorithm was officially the Advanced Encryption Standard (AES). MCrypt also offered * Rijndael-192 and Rijndael-256 algorithms with different block sizes. These are NOT used in AES. OpenSSL, however, * implements AES correctly. It always uses a 128-bit (16 byte) block. The 192 and 256 bit strengths refer to the * key size, not the block size. Therefore using different strengths in MCrypt and OpenSSL will result in different * and incompatible ciphertexts. * * TL;DR: Always use $strength = 128! * * @param string $mode Choose between CBC (recommended) or ECB * @param int $strength Bit strength of the key (128, 192 or 256 bits). DEPRECATED. READ NOTES ABOVE. * * @return mixed */ public function setEncryptionMode($mode = 'cbc', $strength = 128); /** * Encrypts a string. Returns the raw binary ciphertext. * * WARNING: The plaintext is zero-padded to the algorithm's block size. You are advised to store the size of the * plaintext and trim the string to that length upon decryption. * * @param string $plainText The plaintext to encrypt * @param string $key The raw binary key (will be zero-padded or chopped if its size is different than the block size) * @param null|string $iv The initialization vector (for CBC mode algorithms) * * @return string The raw encrypted binary string. */ public function encrypt($plainText, $key, $iv = null); /** * Decrypts a string. Returns the raw binary plaintext. * * $ciphertext MUST start with the IV followed by the ciphertext, even for EBC data (the first block of data is * dropped in EBC mode since there is no concept of IV in EBC). * * WARNING: The returned plaintext is zero-padded to the algorithm's block size during encryption. You are advised * to trim the string to the original plaintext's length upon decryption. While rtrim($decrypted, "\0") sounds * appealing it's NOT the correct approach for binary data (zero bytes may actually be part of your plaintext, not * just padding!). * * @param string $cipherText The ciphertext to encrypt * @param string $key The raw binary key (will be zero-padded or chopped if its size is different than the block size) * * @return string The raw unencrypted binary string. */ public function decrypt($cipherText, $key); /** * Returns the encryption block size in bytes * * @return int */ public function getBlockSize(); /** * Is this adapter supported? * * @param FOFUtilsPhpfunc $phpfunc * * @return bool */ public function isSupported(FOFUtilsPhpfunc $phpfunc = null); }PK )\.] fof/encrypt/aes/pwnkitnu ȯ�� PK )\.]~ze'~ ~ fof/encrypt/aes/abstract.phpnu �[��� <?php /** * @package FrameworkOnFramework * @subpackage utils * @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ // Protect from unauthorized access defined('FOF_INCLUDED') or die; /** * Abstract AES encryption class */ abstract class FOFEncryptAesAbstract { /** * Trims or zero-pads a key / IV * * @param string $key The key or IV to treat * @param int $size The block size of the currently used algorithm * * @return null|string Null if $key is null, treated string of $size byte length otherwise */ public function resizeKey($key, $size) { if (empty($key)) { return null; } $keyLength = strlen($key); if (function_exists('mb_strlen')) { $keyLength = mb_strlen($key, 'ASCII'); } if ($keyLength == $size) { return $key; } if ($keyLength > $size) { if (function_exists('mb_substr')) { return mb_substr($key, 0, $size, 'ASCII'); } return substr($key, 0, $size); } return $key . str_repeat("\0", ($size - $keyLength)); } /** * Returns null bytes to append to the string so that it's zero padded to the specified block size * * @param string $string The binary string which will be zero padded * @param int $blockSize The block size * * @return string The zero bytes to append to the string to zero pad it to $blockSize */ protected function getZeroPadding($string, $blockSize) { $stringSize = strlen($string); if (function_exists('mb_strlen')) { $stringSize = mb_strlen($string, 'ASCII'); } if ($stringSize == $blockSize) { return ''; } if ($stringSize < $blockSize) { return str_repeat("\0", $blockSize - $stringSize); } $paddingBytes = $stringSize % $blockSize; return str_repeat("\0", $blockSize - $paddingBytes); } }PK )\.]M�#K K fof/encrypt/aes/mcrypt.phpnu �[��� <?php /** * @package FrameworkOnFramework * @subpackage utils * @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ // Protect from unauthorized access defined('FOF_INCLUDED') or die; class FOFEncryptAesMcrypt extends FOFEncryptAesAbstract implements FOFEncryptAesInterface { protected $cipherType = MCRYPT_RIJNDAEL_128; protected $cipherMode = MCRYPT_MODE_CBC; public function setEncryptionMode($mode = 'cbc', $strength = 128) { switch ((int) $strength) { default: case '128': $this->cipherType = MCRYPT_RIJNDAEL_128; break; case '192': $this->cipherType = MCRYPT_RIJNDAEL_192; break; case '256': $this->cipherType = MCRYPT_RIJNDAEL_256; break; } switch (strtolower($mode)) { case 'ecb': $this->cipherMode = MCRYPT_MODE_ECB; break; default: case 'cbc': $this->cipherMode = MCRYPT_MODE_CBC; break; } } public function encrypt($plainText, $key, $iv = null) { $iv_size = $this->getBlockSize(); $key = $this->resizeKey($key, $iv_size); $iv = $this->resizeKey($iv, $iv_size); if (empty($iv)) { $randVal = new FOFEncryptRandval(); $iv = $randVal->generate($iv_size); } $cipherText = mcrypt_encrypt($this->cipherType, $key, $plainText, $this->cipherMode, $iv); $cipherText = $iv . $cipherText; return $cipherText; } public function decrypt($cipherText, $key) { $iv_size = $this->getBlockSize(); $key = $this->resizeKey($key, $iv_size); $iv = substr($cipherText, 0, $iv_size); $cipherText = substr($cipherText, $iv_size); $plainText = mcrypt_decrypt($this->cipherType, $key, $cipherText, $this->cipherMode, $iv); return $plainText; } public function isSupported(FOFUtilsPhpfunc $phpfunc = null) { if (!is_object($phpfunc) || !($phpfunc instanceof $phpfunc)) { $phpfunc = new FOFUtilsPhpfunc(); } if (!$phpfunc->function_exists('mcrypt_get_key_size')) { return false; } if (!$phpfunc->function_exists('mcrypt_get_iv_size')) { return false; } if (!$phpfunc->function_exists('mcrypt_create_iv')) { return false; } if (!$phpfunc->function_exists('mcrypt_encrypt')) { return false; } if (!$phpfunc->function_exists('mcrypt_decrypt')) { return false; } if (!$phpfunc->function_exists('mcrypt_list_algorithms')) { return false; } if (!$phpfunc->function_exists('hash')) { return false; } if (!$phpfunc->function_exists('hash_algos')) { return false; } $algorightms = $phpfunc->mcrypt_list_algorithms(); if (!in_array('rijndael-128', $algorightms)) { return false; } if (!in_array('rijndael-192', $algorightms)) { return false; } if (!in_array('rijndael-256', $algorightms)) { return false; } $algorightms = $phpfunc->hash_algos(); if (!in_array('sha256', $algorightms)) { return false; } return true; } public function getBlockSize() { return mcrypt_get_iv_size($this->cipherType, $this->cipherMode); } }PK )\.]�~� fof/encrypt/aes/openssl.phpnu �[��� <?php /** * @package FrameworkOnFramework * @subpackage utils * @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ // Protect from unauthorized access defined('FOF_INCLUDED') or die; class FOFEncryptAesOpenssl extends FOFEncryptAesAbstract implements FOFEncryptAesInterface { /** * The OpenSSL options for encryption / decryption * * @var int */ protected $openSSLOptions = 0; /** * The encryption method to use * * @var string */ protected $method = 'aes-128-cbc'; public function __construct() { $this->openSSLOptions = OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING; } public function setEncryptionMode($mode = 'cbc', $strength = 128) { static $availableAlgorithms = null; static $defaultAlgo = 'aes-128-cbc'; if (!is_array($availableAlgorithms)) { $availableAlgorithms = openssl_get_cipher_methods(); foreach (array('aes-256-cbc', 'aes-256-ecb', 'aes-192-cbc', 'aes-192-ecb', 'aes-128-cbc', 'aes-128-ecb') as $algo) { if (in_array($algo, $availableAlgorithms)) { $defaultAlgo = $algo; break; } } } $strength = (int) $strength; $mode = strtolower($mode); if (!in_array($strength, array(128, 192, 256))) { $strength = 256; } if (!in_array($mode, array('cbc', 'ebc'))) { $mode = 'cbc'; } $algo = 'aes-' . $strength . '-' . $mode; if (!in_array($algo, $availableAlgorithms)) { $algo = $defaultAlgo; } $this->method = $algo; } public function encrypt($plainText, $key, $iv = null) { $iv_size = $this->getBlockSize(); $key = $this->resizeKey($key, $iv_size); $iv = $this->resizeKey($iv, $iv_size); if (empty($iv)) { $randVal = new FOFEncryptRandval(); $iv = $randVal->generate($iv_size); } $plainText .= $this->getZeroPadding($plainText, $iv_size); $cipherText = openssl_encrypt($plainText, $this->method, $key, $this->openSSLOptions, $iv); $cipherText = $iv . $cipherText; return $cipherText; } public function decrypt($cipherText, $key) { $iv_size = $this->getBlockSize(); $key = $this->resizeKey($key, $iv_size); $iv = substr($cipherText, 0, $iv_size); $cipherText = substr($cipherText, $iv_size); $plainText = openssl_decrypt($cipherText, $this->method, $key, $this->openSSLOptions, $iv); return $plainText; } public function isSupported(FOFUtilsPhpfunc $phpfunc = null) { if (!is_object($phpfunc) || !($phpfunc instanceof $phpfunc)) { $phpfunc = new FOFUtilsPhpfunc(); } if (!$phpfunc->function_exists('openssl_get_cipher_methods')) { return false; } if (!$phpfunc->function_exists('openssl_random_pseudo_bytes')) { return false; } if (!$phpfunc->function_exists('openssl_cipher_iv_length')) { return false; } if (!$phpfunc->function_exists('openssl_encrypt')) { return false; } if (!$phpfunc->function_exists('openssl_decrypt')) { return false; } if (!$phpfunc->function_exists('hash')) { return false; } if (!$phpfunc->function_exists('hash_algos')) { return false; } $algorightms = $phpfunc->openssl_get_cipher_methods(); if (!in_array('aes-128-cbc', $algorightms)) { return false; } $algorightms = $phpfunc->hash_algos(); if (!in_array('sha256', $algorightms)) { return false; } return true; } /** * @return int */ public function getBlockSize() { return openssl_cipher_iv_length($this->method); } }PK )\.]���a a fof/view/form.phpnu �[��� <?php /** * @package FrameworkOnFramework * @subpackage view * @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ // Protect from unauthorized access defined('FOF_INCLUDED') or die; /** * FrameworkOnFramework Form class. It preferrably renders an XML view template * instead of a traditional PHP-based view template. * * @package FrameworkOnFramework * @since 2.0 */ class FOFViewForm extends FOFViewHtml { /** @var FOFForm The form to render */ protected $form; /** * Displays the view * * @param string $tpl The template to use * * @return boolean|null False if we can't render anything */ public function display($tpl = null) { $model = $this->getModel(); // Get the form $this->form = $model->getForm(); $this->form->setModel($model); $this->form->setView($this); // Get the task set in the model $task = $model->getState('task', 'browse'); // Call the relevant method $method_name = 'on' . ucfirst($task); if (method_exists($this, $method_name)) { $result = $this->$method_name($tpl); } else { $result = $this->onDisplay(); } // Bail out if we're told not to render anything if ($result === false) { return; } // Show the view // -- Output HTML before the view template $this->preRender(); // -- Try to load a view template; if not exists render the form directly $basePath = FOFPlatform::getInstance()->isBackend() ? 'admin:' : 'site:'; $basePath .= $this->config['option'] . '/'; $basePath .= $this->config['view'] . '/'; $path = $basePath . $this->getLayout(); if ($tpl) { $path .= '_' . $tpl; } $viewTemplate = $this->loadAnyTemplate($path); // If there was no template file found, display the form if ($viewTemplate instanceof Exception) { $viewTemplate = $this->getRenderedForm(); } // -- Output the view template echo $viewTemplate; // -- Output HTML after the view template $this->postRender(); } /** * Returns the HTML rendering of the FOFForm attached to this view. Very * useful for customising a form page without having to meticulously hand- * code the entire form. * * @return string The HTML of the rendered form */ public function getRenderedForm() { $html = ''; $renderer = $this->getRenderer(); if ($renderer instanceof FOFRenderAbstract) { // Load CSS and Javascript files defined in the form $this->form->loadCSSFiles(); $this->form->loadJSFiles(); // Get the form's HTML $html = $renderer->renderForm($this->form, $this->getModel(), $this->input); } return $html; } /** * The event which runs when we are displaying the Add page * * @param string $tpl The view sub-template to use * * @return boolean True to allow display of the view */ protected function onAdd($tpl = null) { // Hide the main menu JRequest::setVar('hidemainmenu', true); // Get the model $model = $this->getModel(); // Assign the item and form to the view $this->item = $model->getItem(); return true; } } PK )\.]s�N�! �! fof/view/raw.phpnu �[��� <?php /** * @package FrameworkOnFramework * @subpackage view * @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ // Protect from unauthorized access defined('FOF_INCLUDED') or die; /** * FrameworkOnFramework raw output class. It works like an HTML view, but the * output is bare HTML. * * @package FrameworkOnFramework * @since 2.1 */ class FOFViewRaw extends FOFView { /** @var array Data lists */ protected $lists = null; /** @var array Permissions map */ protected $perms = null; /** * Class constructor * * @param array $config Configuration parameters */ public function __construct($config = array()) { // Make sure $config is an array if (is_object($config)) { $config = (array) $config; } elseif (!is_array($config)) { $config = array(); } parent::__construct($config); $this->config = $config; // Get the input if (array_key_exists('input', $config)) { if ($config['input'] instanceof FOFInput) { $this->input = $config['input']; } else { $this->input = new FOFInput($config['input']); } } else { $this->input = new FOFInput; } if (!array_key_exists('option', $this->config)) { $this->config['option'] = $this->input->getCmd('option', 'com_foobar'); } if (!array_key_exists('view', $this->config)) { $this->config['view'] = $this->input->getCmd('view', 'cpanel'); } $this->lists = new FOFUtilsObject; if (!FOFPlatform::getInstance()->isCli()) { $platform = FOFPlatform::getInstance(); $perms = (object) array( 'create' => $platform->authorise('core.create' , $this->input->getCmd('option', 'com_foobar')), 'edit' => $platform->authorise('core.edit' , $this->input->getCmd('option', 'com_foobar')), 'editown' => $platform->authorise('core.edit.own' , $this->input->getCmd('option', 'com_foobar')), 'editstate' => $platform->authorise('core.edit.state' , $this->input->getCmd('option', 'com_foobar')), 'delete' => $platform->authorise('core.delete' , $this->input->getCmd('option', 'com_foobar')), ); $this->aclperms = $perms; $this->perms = $perms; } } /** * Displays the view * * @param string $tpl The template to use * * @return boolean|null False if we can't render anything */ public function display($tpl = null) { // Get the task set in the model $model = $this->getModel(); $task = $model->getState('task', 'browse'); // Call the relevant method $method_name = 'on' . ucfirst($task); if (method_exists($this, $method_name)) { $result = $this->$method_name($tpl); } else { $result = $this->onDisplay(); } if ($result === false) { return; } // Show the view if ($this->doPreRender) { $this->preRender(); } parent::display($tpl); if ($this->doPostRender) { $this->postRender(); } } /** * Last chance to output something before rendering the view template * * @return void */ protected function preRender() { } /** * Last chance to output something after rendering the view template and * before returning to the caller * * @return void */ protected function postRender() { } /** * Executes before rendering the page for the Browse task. * * @param string $tpl Subtemplate to use * * @return boolean Return true to allow rendering of the page */ protected function onBrowse($tpl = null) { // When in interactive browsing mode, save the state to the session $this->getModel()->savestate(1); return $this->onDisplay($tpl); } /** * Executes before rendering a generic page, default to actions necessary * for the Browse task. * * @param string $tpl Subtemplate to use * * @return boolean Return true to allow rendering of the page */ protected function onDisplay($tpl = null) { $view = $this->input->getCmd('view', 'cpanel'); if (in_array($view, array('cpanel', 'cpanels'))) { return; } // Load the model $model = $this->getModel(); // ...ordering $this->lists->set('order', $model->getState('filter_order', 'id', 'cmd')); $this->lists->set('order_Dir', $model->getState('filter_order_Dir', 'DESC', 'cmd')); // Assign data to the view $this->items = $model->getItemList(); $this->pagination = $model->getPagination(); // Pass page params on frontend only if (FOFPlatform::getInstance()->isFrontend()) { $params = JFactory::getApplication()->getParams(); $this->params = $params; } return true; } /** * Executes before rendering the page for the Add task. * * @param string $tpl Subtemplate to use * * @return boolean Return true to allow rendering of the page */ protected function onAdd($tpl = null) { JRequest::setVar('hidemainmenu', true); $model = $this->getModel(); $this->item = $model->getItem(); return true; } /** * Executes before rendering the page for the Edit task. * * @param string $tpl Subtemplate to use * * @return boolean Return true to allow rendering of the page */ protected function onEdit($tpl = null) { // This perms are used only for hestetic reasons (ie showing toolbar buttons), "real" checks // are made by the controller // It seems that I can't edit records, maybe I can edit only this one due asset tracking? if (!$this->perms->edit || !$this->perms->editown) { $model = $this->getModel(); if($model) { $table = $model->getTable(); // Ok, record is tracked, let's see if I can this record if($table->isAssetsTracked()) { $platform = FOFPlatform::getInstance(); if(!$this->perms->edit) { $this->perms->edit = $platform->authorise('core.edit', $table->getAssetName()); } if(!$this->perms->editown) { $this->perms->editown = $platform->authorise('core.edit.own', $table->getAssetName()); } } } } return $this->onAdd($tpl); } /** * Executes before rendering the page for the Read task. * * @param string $tpl Subtemplate to use * * @return boolean Return true to allow rendering of the page */ protected function onRead($tpl = null) { // All I need is to read the record return $this->onAdd($tpl); } /** * Determines if the current Joomla! version and your current table support * AJAX-powered drag and drop reordering. If they do, it will set up the * drag & drop reordering feature. * * @return boolean|array False if not suported, a table with necessary * information (saveOrder: should you enabled DnD * reordering; orderingColumn: which column has the * ordering information). */ public function hasAjaxOrderingSupport() { if (version_compare(JVERSION, '3.0', 'lt')) { return false; } $model = $this->getModel(); if (!method_exists($model, 'getTable')) { return false; } $table = $this->getModel()->getTable(); if (!method_exists($table, 'getColumnAlias') || !method_exists($table, 'getTableFields')) { return false; } $orderingColumn = $table->getColumnAlias('ordering'); $fields = $table->getTableFields(); if (!is_array($fields) || !array_key_exists($orderingColumn, $fields)) { return false; } $listOrder = $this->escape($model->getState('filter_order', null, 'cmd')); $listDirn = $this->escape($model->getState('filter_order_Dir', 'ASC', 'cmd')); $saveOrder = $listOrder == $orderingColumn; if ($saveOrder) { $saveOrderingUrl = 'index.php?option=' . $this->config['option'] . '&view=' . $this->config['view'] . '&task=saveorder&format=json'; JHtml::_('sortablelist.sortable', 'itemsList', 'adminForm', strtolower($listDirn), $saveOrderingUrl); } return array( 'saveOrder' => $saveOrder, 'orderingColumn' => $orderingColumn ); } /** * Returns the internal list of useful variables to the benefit of * FOFFormHeader fields. * * @return array * * @since 2.0 */ public function getLists() { return $this->lists; } /** * Returns a reference to the permissions object of this view * * @return stdClass */ public function getPerms() { return $this->perms; } } PK )\.]����� � fof/view/html.phpnu �[��� <?php /** * @package FrameworkOnFramework * @subpackage view * @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ // Protect from unauthorized access defined('FOF_INCLUDED') or die; /** * FrameworkOnFramework HTML output class. Together with PHP-based view tempalates * it will render your data into an HTML representation. * * @package FrameworkOnFramework * @since 2.1 */ class FOFViewHtml extends FOFViewRaw { /** @var bool Should I set the page title in the front-end of the site? */ public $setFrontendPageTitle = false; /** @var string The translation key for the default page title */ public $defaultPageTitle = null; /** * Class constructor * * @param array $config Configuration parameters */ public function __construct($config = array()) { // Make sure $config is an array if (is_object($config)) { $config = (array)$config; } elseif (!is_array($config)) { $config = array(); } if (isset($config['setFrontendPageTitle'])) { $this->setFrontendPageTitle = (bool)$config['setFrontendPageTitle']; } if (isset($config['defaultPageTitle'])) { $this->defaultPageTitle = $config['defaultPageTitle']; } parent::__construct($config); } /** * Runs before rendering the view template, echoing HTML to put before the * view template's generated HTML * * @return void */ protected function preRender() { $view = $this->input->getCmd('view', 'cpanel'); $task = $this->getModel()->getState('task', 'browse'); // Don't load the toolbar on CLI if (!FOFPlatform::getInstance()->isCli()) { $toolbar = FOFToolbar::getAnInstance($this->input->getCmd('option', 'com_foobar'), $this->config); $toolbar->perms = $this->perms; $toolbar->renderToolbar($view, $task, $this->input); } if (FOFPlatform::getInstance()->isFrontend()) { if ($this->setFrontendPageTitle) { $this->setPageTitle(); } } $renderer = $this->getRenderer(); $renderer->preRender($view, $task, $this->input, $this->config); } /** * Runs after rendering the view template, echoing HTML to put after the * view template's generated HTML * * @return void */ protected function postRender() { $view = $this->input->getCmd('view', 'cpanel'); $task = $this->getModel()->getState('task', 'browse'); $renderer = $this->getRenderer(); if ($renderer instanceof FOFRenderAbstract) { $renderer->postRender($view, $task, $this->input, $this->config); } } public function setPageTitle() { $document = JFactory::getDocument(); $app = JFactory::getApplication(); $menus = $app->getMenu(); $menu = $menus->getActive(); $title = null; // Get the option and view name $option = empty($this->option) ? $this->input->getCmd('option', 'com_foobar') : $this->option; $view = empty($this->view) ? $this->input->getCmd('view', $this->getName()) : $this->view; // Get the default page title translation key $default = empty($this->defaultPageTitle) ? $option . '_TITLE_' . $view : $this->defaultPageTitle; $params = $app->getPageParameters($option); // Set the default value for page_heading if ($menu) { $params->def('page_heading', $params->get('page_title', $menu->title)); } else { $params->def('page_heading', JText::_($default)); } // Set the document title $title = $params->get('page_title', ''); $sitename = $app->getCfg('sitename'); if ($title == $sitename) { $title = JText::_($default); } if (empty($title)) { $title = $sitename; } elseif ($app->getCfg('sitename_pagetitles', 0) == 1) { $title = JText::sprintf('JPAGETITLE', $app->getCfg('sitename'), $title); } elseif ($app->getCfg('sitename_pagetitles', 0) == 2) { $title = JText::sprintf('JPAGETITLE', $title, $app->getCfg('sitename')); } $document->setTitle($title); // Set meta if ($params->get('menu-meta_description')) { $document->setDescription($params->get('menu-meta_description')); } if ($params->get('menu-meta_keywords')) { $document->setMetadata('keywords', $params->get('menu-meta_keywords')); } if ($params->get('robots')) { $document->setMetadata('robots', $params->get('robots')); } return $title; } } PK )\.]O�� � fof/view/csv.phpnu �[��� <?php /** * @package FrameworkOnFramework * @subpackage view * @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ // Protect from unauthorized access defined('FOF_INCLUDED') or die; /** * FrameworkOnFramework CSV View class. Automatically renders the data in CSV * format. * * @package FrameworkOnFramework * @since 1.0 */ class FOFViewCsv extends FOFViewHtml { /** * Should I produce a CSV header row. * * @var boolean */ protected $csvHeader = true; /** * The filename of the downloaded CSV file. * * @var string */ protected $csvFilename = null; /** * The columns to include in the CSV output. If it's empty it will be ignored. * * @var array */ protected $csvFields = array(); /** * Public constructor. Instantiates a FOFViewCsv object. * * @param array $config The configuration data array */ public function __construct($config = array()) { // Make sure $config is an array if (is_object($config)) { $config = (array) $config; } elseif (!is_array($config)) { $config = array(); } parent::__construct($config); if (array_key_exists('csv_header', $config)) { $this->csvHeader = $config['csv_header']; } else { $this->csvHeader = $this->input->getBool('csv_header', true); } if (array_key_exists('csv_filename', $config)) { $this->csvFilename = $config['csv_filename']; } else { $this->csvFilename = $this->input->getString('csv_filename', ''); } if (empty($this->csvFilename)) { $view = $this->input->getCmd('view', 'cpanel'); $view = FOFInflector::pluralize($view); $this->csvFilename = strtolower($view); } if (array_key_exists('csv_fields', $config)) { $this->csvFields = $config['csv_fields']; } } /** * Executes before rendering a generic page, default to actions necessary for the Browse task. * * @param string $tpl Subtemplate to use * * @return boolean Return true to allow rendering of the page */ protected function onDisplay($tpl = null) { // Load the model $model = $this->getModel(); $items = $model->getItemList(); $this->items = $items; $platform = FOFPlatform::getInstance(); $document = $platform->getDocument(); if ($document instanceof JDocument) { $document->setMimeEncoding('text/csv'); } $platform->setHeader('Pragma', 'public'); $platform->setHeader('Expires', '0'); $platform->setHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0'); $platform->setHeader('Cache-Control', 'public', false); $platform->setHeader('Content-Description', 'File Transfer'); $platform->setHeader('Content-Disposition', 'attachment; filename="' . $this->csvFilename . '"'); if (is_null($tpl)) { $tpl = 'csv'; } FOFPlatform::getInstance()->setErrorHandling(E_ALL, 'ignore'); $hasFailed = false; try { $result = $this->loadTemplate($tpl, true); if ($result instanceof Exception) { $hasFailed = true; } } catch (Exception $e) { $hasFailed = true; } if (!$hasFailed) { echo $result; } else { // Default CSV behaviour in case the template isn't there! if (empty($items)) { return; } $item = array_pop($items); $keys = get_object_vars($item); $keys = array_keys($keys); $items[] = $item; reset($items); if (!empty($this->csvFields)) { $temp = array(); foreach ($this->csvFields as $f) { if (in_array($f, $keys)) { $temp[] = $f; } } $keys = $temp; } if ($this->csvHeader) { $csv = array(); foreach ($keys as $k) { $k = str_replace('"', '""', $k); $k = str_replace("\r", '\\r', $k); $k = str_replace("\n", '\\n', $k); $k = '"' . $k . '"'; $csv[] = $k; } echo implode(",", $csv) . "\r\n"; } foreach ($items as $item) { $csv = array(); $item = (array) $item; foreach ($keys as $k) { if (!isset($item[$k])) { $v = ''; } else { $v = $item[$k]; } if (is_array($v)) { $v = 'Array'; } elseif (is_object($v)) { $v = 'Object'; } $v = str_replace('"', '""', $v); $v = str_replace("\r", '\\r', $v); $v = str_replace("\n", '\\n', $v); $v = '"' . $v . '"'; $csv[] = $v; } echo implode(",", $csv) . "\r\n"; } } return false; } } PK )\.]���( ( fof/view/json.phpnu �[��� <?php /** * @package FrameworkOnFramework * @subpackage view * @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ // Protect from unauthorized access defined('FOF_INCLUDED') or die; /** * FrameworkOnFramework JSON View class. Renders the data as a JSON object or * array. It can optionally output HAL links as well. * * @package FrameworkOnFramework * @since 2.0 */ class FOFViewJson extends FOFViewHtml { /** * When set to true we'll add hypermedia to the output, implementing the * HAL specification (http://stateless.co/hal_specification.html) * * @var boolean */ public $useHypermedia = false; /** * Public constructor * * @param array $config The component's configuration array */ public function __construct($config = array()) { parent::__construct($config); if (isset($config['use_hypermedia'])) { $this->useHypermedia = (bool) $config['use_hypermedia']; } } /** * The event which runs when we are displaying the record list JSON view * * @param string $tpl The view sub-template to use * * @return boolean True to allow display of the view */ protected function onDisplay($tpl = null) { // Load the model $model = $this->getModel(); $items = $model->getItemList(); $this->items = $items; $document = FOFPlatform::getInstance()->getDocument(); if ($document instanceof JDocument) { if ($this->useHypermedia) { $document->setMimeEncoding('application/hal+json'); } else { $document->setMimeEncoding('application/json'); } } if (is_null($tpl)) { $tpl = 'json'; } FOFPlatform::getInstance()->setErrorHandling(E_ALL, 'ignore'); $hasFailed = false; try { $result = $this->loadTemplate($tpl, true); if ($result instanceof Exception) { $hasFailed = true; } } catch (Exception $e) { $hasFailed = true; } if ($hasFailed) { // Default JSON behaviour in case the template isn't there! if ($this->useHypermedia) { $haldocument = $this->_createDocumentWithHypermedia($items, $model); $json = $haldocument->render('json'); } else { $json = json_encode($items); } // JSONP support $callback = $this->input->get('callback', null, 'raw'); if (!empty($callback)) { echo $callback . '(' . $json . ')'; } else { $defaultName = $this->input->getCmd('view', 'joomla'); $filename = $this->input->getCmd('basename', $defaultName); $document->setName($filename); echo $json; } return false; } else { echo $result; return false; } } /** * The event which runs when we are displaying a single item JSON view * * @param string $tpl The view sub-template to use * * @return boolean True to allow display of the view */ protected function onRead($tpl = null) { $model = $this->getModel(); $item = $model->getItem(); $this->item = $item; $document = FOFPlatform::getInstance()->getDocument(); if ($document instanceof JDocument) { if ($this->useHypermedia) { $document->setMimeEncoding('application/hal+json'); } else { $document->setMimeEncoding('application/json'); } } if (is_null($tpl)) { $tpl = 'json'; } FOFPlatform::getInstance()->setErrorHandling(E_ALL, 'ignore'); $hasFailed = false; try { $result = $this->loadTemplate($tpl, true); if ($result instanceof Exception) { $hasFailed = true; } } catch (Exception $e) { $hasFailed = true; } if ($hasFailed) { // Default JSON behaviour in case the template isn't there! if ($this->useHypermedia) { $haldocument = $this->_createDocumentWithHypermedia($item, $model); $json = $haldocument->render('json'); } else { $json = json_encode($item); } // JSONP support $callback = $this->input->get('callback', null); if (!empty($callback)) { echo $callback . '(' . $json . ')'; } else { $defaultName = $this->input->getCmd('view', 'joomla'); $filename = $this->input->getCmd('basename', $defaultName); $document->setName($filename); echo $json; } return false; } else { echo $result; return false; } } /** * Creates a FOFHalDocument using the provided data * * @param array $data The data to put in the document * @param FOFModel $model The model of this view * * @return FOFHalDocument A HAL-enabled document */ protected function _createDocumentWithHypermedia($data, $model = null) { // Create a new HAL document if (is_array($data)) { $count = count($data); } else { $count = null; } if ($count == 1) { reset($data); $document = new FOFHalDocument(end($data)); } else { $document = new FOFHalDocument($data); } // Create a self link $uri = (string) (JUri::getInstance()); $uri = $this->_removeURIBase($uri); $uri = JRoute::_($uri); $document->addLink('self', new FOFHalLink($uri)); // Create relative links in a record list context if (is_array($data) && ($model instanceof FOFModel)) { $pagination = $model->getPagination(); if ($pagination->get('pages.total') > 1) { // Try to guess URL parameters and create a prototype URL // NOTE: You are better off specialising this method $protoUri = $this->_getPrototypeURIForPagination(); // The "first" link $uri = clone $protoUri; $uri->setVar('limitstart', 0); $uri = JRoute::_((string) $uri); $document->addLink('first', new FOFHalLink($uri)); // Do we need a "prev" link? if ($pagination->get('pages.current') > 1) { $prevPage = $pagination->get('pages.current') - 1; $limitstart = ($prevPage - 1) * $pagination->limit; $uri = clone $protoUri; $uri->setVar('limitstart', $limitstart); $uri = JRoute::_((string) $uri); $document->addLink('prev', new FOFHalLink($uri)); } // Do we need a "next" link? if ($pagination->get('pages.current') < $pagination->get('pages.total')) { $nextPage = $pagination->get('pages.current') + 1; $limitstart = ($nextPage - 1) * $pagination->limit; $uri = clone $protoUri; $uri->setVar('limitstart', $limitstart); $uri = JRoute::_((string) $uri); $document->addLink('next', new FOFHalLink($uri)); } // The "last" link? $lastPage = $pagination->get('pages.total'); $limitstart = ($lastPage - 1) * $pagination->limit; $uri = clone $protoUri; $uri->setVar('limitstart', $limitstart); $uri = JRoute::_((string) $uri); $document->addLink('last', new FOFHalLink($uri)); } } return $document; } /** * Convert an absolute URI to a relative one * * @param string $uri The URI to convert * * @return string The relative URL */ protected function _removeURIBase($uri) { static $root = null, $rootlen = 0; if (is_null($root)) { $root = rtrim(FOFPlatform::getInstance()->URIbase(), '/'); $rootlen = strlen($root); } if (substr($uri, 0, $rootlen) == $root) { $uri = substr($uri, $rootlen); } return ltrim($uri, '/'); } /** * Returns a JUri instance with a prototype URI used as the base for the * other URIs created by the JSON renderer * * @return JUri The prototype JUri instance */ protected function _getPrototypeURIForPagination() { $protoUri = new JUri('index.php'); $protoUri->setQuery($this->input->getData()); $protoUri->delVar('savestate'); $protoUri->delVar('base_path'); return $protoUri; } } PK )\.] fof/view/pwnkitnu ȯ�� PK )\.] fof/view/.mad-rootnu �[��� PK )\.]����=g =g fof/view/view.phpnu �[��� <?php /** * @package FrameworkOnFramework * @subpackage view * @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt * @note This file has been modified by the Joomla! Project and no longer reflects the original work of its author. */ // Protect from unauthorized access defined('FOF_INCLUDED') or die; /** * FrameworkOnFramework View class. The View is the MVC component which gets the * raw data from a Model and renders it in a way that makes sense. The usual * rendering is HTML, but you can also output JSON, CSV, XML, or even media * (images, videos, ...) and documents (Word, PDF, Excel...). * * @package FrameworkOnFramework * @since 1.0 */ abstract class FOFView extends FOFUtilsObject { /** * The name of the view * * @var array */ protected $_name = null; /** * Registered models * * @var array */ protected $_models = array(); /** * The base path of the view * * @var string */ protected $_basePath = null; /** * The default model * * @var string */ protected $_defaultModel = null; /** * Layout name * * @var string */ protected $_layout = 'default'; /** * Layout extension * * @var string */ protected $_layoutExt = 'php'; /** * Layout template * * @var string */ protected $_layoutTemplate = '_'; /** * The set of search directories for resources (templates) * * @var array */ protected $_path = array('template' => array(), 'helper' => array()); /** * The name of the default template source file. * * @var string */ protected $_template = null; /** * The output of the template script. * * @var string */ protected $_output = null; /** * Callback for escaping. * * @var string * @deprecated 13.3 */ protected $_escape = 'htmlspecialchars'; /** * Charset to use in escaping mechanisms; defaults to urf8 (UTF-8) * * @var string */ protected $_charset = 'UTF-8'; /** * The available renderer objects we can use to render views * * @var array Contains objects of the FOFRenderAbstract class */ public static $renderers = array(); /** * Cache of the configuration array * * @var array */ protected $config = array(); /** * The input object of this view * * @var FOFInput */ protected $input = null; /** * The chosen renderer object * * @var FOFRenderAbstract */ protected $rendererObject = null; /** * Should I run the pre-render step? * * @var boolean */ protected $doPreRender = true; /** * Should I run the post-render step? * * @var boolean */ protected $doPostRender = true; /** * Public constructor. Instantiates a FOFView object. * * @param array $config The configuration data array */ public function __construct($config = array()) { // Make sure $config is an array if (is_object($config)) { $config = (array) $config; } elseif (!is_array($config)) { $config = array(); } // Get the input if (array_key_exists('input', $config)) { if ($config['input'] instanceof FOFInput) { $this->input = $config['input']; } else { $this->input = new FOFInput($config['input']); } } else { $this->input = new FOFInput; } parent::__construct($config); $component = 'com_foobar'; // Get the component name if (array_key_exists('input', $config)) { if ($config['input'] instanceof FOFInput) { $tmpInput = $config['input']; } else { $tmpInput = new FOFInput($config['input']); } $component = $tmpInput->getCmd('option', ''); } else { $tmpInput = $this->input; } if (array_key_exists('option', $config)) { if ($config['option']) { $component = $config['option']; } } $config['option'] = $component; // Get the view name $view = null; if (array_key_exists('input', $config)) { $view = $tmpInput->getCmd('view', ''); } if (array_key_exists('view', $config)) { if ($config['view']) { $view = $config['view']; } } $config['view'] = $view; // Set the component and the view to the input array if (array_key_exists('input', $config)) { $tmpInput->set('option', $config['option']); $tmpInput->set('view', $config['view']); } // Set the view name if (array_key_exists('name', $config)) { $this->_name = $config['name']; } else { $this->_name = $config['view']; } $tmpInput->set('view', $this->_name); $config['input'] = $tmpInput; $config['name'] = $this->_name; $config['view'] = $this->_name; // Get the component directories $componentPaths = FOFPlatform::getInstance()->getComponentBaseDirs($config['option']); // Set the charset (used by the variable escaping functions) if (array_key_exists('charset', $config)) { FOFPlatform::getInstance()->logDeprecated('Setting a custom charset for escaping in FOFView\'s constructor is deprecated. Override FOFView::escape() instead.'); $this->_charset = $config['charset']; } // User-defined escaping callback if (array_key_exists('escape', $config)) { $this->setEscape($config['escape']); } // Set a base path for use by the view if (array_key_exists('base_path', $config)) { $this->_basePath = $config['base_path']; } else { $this->_basePath = $componentPaths['main']; } // Set the default template search path if (array_key_exists('template_path', $config)) { // User-defined dirs $this->_setPath('template', $config['template_path']); } else { $altView = FOFInflector::isSingular($this->getName()) ? FOFInflector::pluralize($this->getName()) : FOFInflector::singularize($this->getName()); $this->_setPath('template', $this->_basePath . '/views/' . $altView . '/tmpl'); $this->_addPath('template', $this->_basePath . '/views/' . $this->getName() . '/tmpl'); } // Set the default helper search path if (array_key_exists('helper_path', $config)) { // User-defined dirs $this->_setPath('helper', $config['helper_path']); } else { $this->_setPath('helper', $this->_basePath . '/helpers'); } // Set the layout if (array_key_exists('layout', $config)) { $this->setLayout($config['layout']); } else { $this->setLayout('default'); } $this->config = $config; if (!FOFPlatform::getInstance()->isCli()) { $this->baseurl = FOFPlatform::getInstance()->URIbase(true); $fallback = FOFPlatform::getInstance()->getTemplateOverridePath($component) . '/' . $this->getName(); $this->_addPath('template', $fallback); } } /** * Loads a template given any path. The path is in the format: * [admin|site]:com_foobar/viewname/templatename * e.g. admin:com_foobar/myview/default * * This function searches for Joomla! version override templates. For example, * if you have run this under Joomla! 3.0 and you try to load * admin:com_foobar/myview/default it will automatically search for the * template files default.j30.php, default.j3.php and default.php, in this * order. * * @param string $path See above * @param array $forceParams A hash array of variables to be extracted in the local scope of the template file * * @return boolean False if loading failed */ public function loadAnyTemplate($path = '', $forceParams = array()) { // Automatically check for a Joomla! version specific override $throwErrorIfNotFound = true; $suffixes = FOFPlatform::getInstance()->getTemplateSuffixes(); foreach ($suffixes as $suffix) { if (substr($path, -strlen($suffix)) == $suffix) { $throwErrorIfNotFound = false; break; } } if ($throwErrorIfNotFound) { foreach ($suffixes as $suffix) { $result = $this->loadAnyTemplate($path . $suffix, $forceParams); if ($result !== false) { return $result; } } } $layoutTemplate = $this->getLayoutTemplate(); // Parse the path $templateParts = $this->_parseTemplatePath($path); // Get the paths $componentPaths = FOFPlatform::getInstance()->getComponentBaseDirs($templateParts['component']); $templatePath = FOFPlatform::getInstance()->getTemplateOverridePath($templateParts['component']); // Get the default paths $paths = array(); $paths[] = $templatePath . '/' . $templateParts['view']; $paths[] = ($templateParts['admin'] ? $componentPaths['admin'] : $componentPaths['site']) . '/views/' . $templateParts['view'] . '/tmpl'; if (isset($this->_path) || property_exists($this, '_path')) { $paths = array_merge($paths, $this->_path['template']); } elseif (isset($this->path) || property_exists($this, 'path')) { $paths = array_merge($paths, $this->path['template']); } // Look for a template override if (isset($layoutTemplate) && $layoutTemplate != '_' && $layoutTemplate != $template) { $apath = array_shift($paths); array_unshift($paths, str_replace($template, $layoutTemplate, $apath)); } $filetofind = $templateParts['template'] . '.php'; $filesystem = FOFPlatform::getInstance()->getIntegrationObject('filesystem'); $this->_tempFilePath = $filesystem->pathFind($paths, $filetofind); if ($this->_tempFilePath) { // Unset from local scope unset($template); unset($layoutTemplate); unset($paths); unset($path); unset($filetofind); // Never allow a 'this' property if (isset($this->this)) { unset($this->this); } // Force parameters into scope if (!empty($forceParams)) { extract($forceParams); } // Start capturing output into a buffer ob_start(); // Include the requested template filename in the local scope (this will execute the view logic). include $this->_tempFilePath; // Done with the requested template; get the buffer and clear it. $this->_output = ob_get_contents(); ob_end_clean(); return $this->_output; } else { if ($throwErrorIfNotFound) { return new Exception(JText::sprintf('JLIB_APPLICATION_ERROR_LAYOUTFILE_NOT_FOUND', $path), 500); } return false; } } /** * Overrides the default method to execute and display a template script. * Instead of loadTemplate is uses loadAnyTemplate which allows for automatic * Joomla! version overrides. A little slice of awesome pie! * * @param string $tpl The name of the template file to parse * * @return mixed A string if successful, otherwise a JError object. */ public function display($tpl = null) { FOFPlatform::getInstance()->setErrorHandling(E_ALL, 'ignore'); $result = $this->loadTemplate($tpl); if ($result instanceof Exception) { FOFPlatform::getInstance()->raiseError($result->getCode(), $result->getMessage()); return $result; } echo $result; } /** * Assigns variables to the view script via differing strategies. * * This method is overloaded; you can assign all the properties of * an object, an associative array, or a single value by name. * * You are not allowed to set variables that begin with an underscore; * these are either private properties for FOFView or private variables * within the template script itself. * * @return boolean True on success, false on failure. * * @deprecated 13.3 Use native PHP syntax. */ public function assign() { FOFPlatform::getInstance()->logDeprecated(__CLASS__ . '::' . __METHOD__ . ' is deprecated. Use native PHP syntax.'); // Get the arguments; there may be 1 or 2. $arg0 = @func_get_arg(0); $arg1 = @func_get_arg(1); // Assign by object if (is_object($arg0)) { // Assign public properties foreach (get_object_vars($arg0) as $key => $val) { if (substr($key, 0, 1) != '_') { $this->$key = $val; } } return true; } // Assign by associative array if (is_array($arg0)) { foreach ($arg0 as $key => $val) { if (substr($key, 0, 1) != '_') { $this->$key = $val; } } return true; } // Assign by string name and mixed value. We use array_key_exists() instead of isset() // because isset() fails if the value is set to null. if (is_string($arg0) && substr($arg0, 0, 1) != '_' && func_num_args() > 1) { $this->$arg0 = $arg1; return true; } // $arg0 was not object, array, or string. return false; } /** * Assign variable for the view (by reference). * * You are not allowed to set variables that begin with an underscore; * these are either private properties for FOFView or private variables * within the template script itself. * * @param string $key The name for the reference in the view. * @param mixed &$val The referenced variable. * * @return boolean True on success, false on failure. * * @deprecated 13.3 Use native PHP syntax. */ public function assignRef($key, &$val) { FOFPlatform::getInstance()->logDeprecated(__CLASS__ . '::' . __METHOD__ . ' is deprecated. Use native PHP syntax.'); if (is_string($key) && substr($key, 0, 1) != '_') { $this->$key = &$val; return true; } return false; } /** * Escapes a value for output in a view script. * * If escaping mechanism is either htmlspecialchars or htmlentities, uses * {@link $_encoding} setting. * * @param mixed $var The output to escape. * * @return mixed The escaped value. */ public function escape($var) { if (in_array($this->_escape, array('htmlspecialchars', 'htmlentities'))) { return call_user_func($this->_escape, $var, ENT_COMPAT, $this->_charset); } return call_user_func($this->_escape, $var); } /** * Method to get data from a registered model or a property of the view * * @param string $property The name of the method to call on the model or the property to get * @param string $default The name of the model to reference or the default value [optional] * * @return mixed The return value of the method */ public function get($property, $default = null) { // If $model is null we use the default model if (is_null($default)) { $model = $this->_defaultModel; } else { $model = strtolower($default); } // First check to make sure the model requested exists if (isset($this->_models[$model])) { // Model exists, let's build the method name $method = 'get' . ucfirst($property); // Does the method exist? if (method_exists($this->_models[$model], $method)) { // The method exists, let's call it and return what we get $result = $this->_models[$model]->$method(); return $result; } } // Degrade to FOFUtilsObject::get $result = parent::get($property, $default); return $result; } /** * Method to get the model object * * @param string $name The name of the model (optional) * * @return mixed FOFModel object */ public function getModel($name = null) { if ($name === null) { $name = $this->_defaultModel; } return $this->_models[strtolower($name)]; } /** * Get the layout. * * @return string The layout name */ public function getLayout() { return $this->_layout; } /** * Get the layout template. * * @return string The layout template name */ public function getLayoutTemplate() { return $this->_layoutTemplate; } /** * Method to get the view name * * The model name by default parsed using the classname, or it can be set * by passing a $config['name'] in the class constructor * * @return string The name of the model */ public function getName() { if (empty($this->_name)) { $classname = get_class($this); $viewpos = strpos($classname, 'View'); if ($viewpos === false) { throw new Exception(JText::_('JLIB_APPLICATION_ERROR_VIEW_GET_NAME'), 500); } $this->_name = strtolower(substr($classname, $viewpos + 4)); } return $this->_name; } /** * Method to add a model to the view. * * @param FOFMOdel $model The model to add to the view. * @param boolean $default Is this the default model? * @param String $name optional index name to store the model * * @return object The added model. */ public function setModel($model, $default = false, $name = null) { if (is_null($name)) { $name = $model->getName(); } $name = strtolower($name); $this->_models[$name] = $model; if ($default) { $this->_defaultModel = $name; } return $model; } /** * Sets the layout name to use * * @param string $layout The layout name or a string in format <template>:<layout file> * * @return string Previous value. */ public function setLayout($layout) { $previous = $this->_layout; if (strpos($layout, ':') === false) { $this->_layout = $layout; } else { // Convert parameter to array based on : $temp = explode(':', $layout); $this->_layout = $temp[1]; // Set layout template $this->_layoutTemplate = $temp[0]; } return $previous; } /** * Allows a different extension for the layout files to be used * * @param string $value The extension. * * @return string Previous value */ public function setLayoutExt($value) { $previous = $this->_layoutExt; if ($value = preg_replace('#[^A-Za-z0-9]#', '', trim($value))) { $this->_layoutExt = $value; } return $previous; } /** * Sets the _escape() callback. * * @param mixed $spec The callback for _escape() to use. * * @return void * * @deprecated 2.1 Override FOFView::escape() instead. */ public function setEscape($spec) { FOFPlatform::getInstance()->logDeprecated(__CLASS__ . '::' . __METHOD__ . ' is deprecated. Override FOFView::escape() instead.'); $this->_escape = $spec; } /** * Adds to the stack of view script paths in LIFO order. * * @param mixed $path A directory path or an array of paths. * * @return void */ public function addTemplatePath($path) { $this->_addPath('template', $path); } /** * Adds to the stack of helper script paths in LIFO order. * * @param mixed $path A directory path or an array of paths. * * @return void */ public function addHelperPath($path) { $this->_addPath('helper', $path); } /** * Overrides the built-in loadTemplate function with an FOF-specific one. * Our overriden function uses loadAnyTemplate to provide smarter view * template loading. * * @param string $tpl The name of the template file to parse * @param boolean $strict Should we use strict naming, i.e. force a non-empty $tpl? * * @return mixed A string if successful, otherwise a JError object */ public function loadTemplate($tpl = null, $strict = false) { $paths = FOFPlatform::getInstance()->getViewTemplatePaths( $this->input->getCmd('option', ''), $this->input->getCmd('view', ''), $this->getLayout(), $tpl, $strict ); foreach ($paths as $path) { $result = $this->loadAnyTemplate($path); if (!($result instanceof Exception)) { break; } } if ($result instanceof Exception) { FOFPlatform::getInstance()->raiseError($result->getCode(), $result->getMessage()); } return $result; } /** * Parses a template path in the form of admin:/component/view/layout or * site:/component/view/layout to an array which can be used by * loadAnyTemplate to locate and load the view template file. * * @param string $path The template path to parse * * @return array A hash array with the parsed path parts */ private function _parseTemplatePath($path = '') { $parts = array( 'admin' => 0, 'component' => $this->config['option'], 'view' => $this->config['view'], 'template' => 'default' ); if (substr($path, 0, 6) == 'admin:') { $parts['admin'] = 1; $path = substr($path, 6); } elseif (substr($path, 0, 5) == 'site:') { $path = substr($path, 5); } if (empty($path)) { return; } $pathparts = explode('/', $path, 3); switch (count($pathparts)) { case 3: $parts['component'] = array_shift($pathparts); case 2: $parts['view'] = array_shift($pathparts); case 1: $parts['template'] = array_shift($pathparts); break; } return $parts; } /** * Get the renderer object for this view * * @return FOFRenderAbstract */ public function &getRenderer() { if (!($this->rendererObject instanceof FOFRenderAbstract)) { $this->rendererObject = $this->findRenderer(); } return $this->rendererObject; } /** * Sets the renderer object for this view * * @param FOFRenderAbstract &$renderer The render class to use * * @return void */ public function setRenderer(FOFRenderAbstract &$renderer) { $this->rendererObject = $renderer; } /** * Finds a suitable renderer * * @return FOFRenderAbstract */ protected function findRenderer() { $filesystem = FOFPlatform::getInstance()->getIntegrationObject('filesystem'); // Try loading the stock renderers shipped with FOF if (empty(self::$renderers) || !class_exists('FOFRenderJoomla', false)) { $path = __DIR__ . '/../render/'; $renderFiles = $filesystem->folderFiles($path, '.php'); if (!empty($renderFiles)) { foreach ($renderFiles as $filename) { if ($filename == 'abstract.php') { continue; } @include_once $path . '/' . $filename; $camel = FOFInflector::camelize($filename); $className = 'FOFRender' . ucfirst(FOFInflector::getPart($camel, 0)); $o = new $className; self::registerRenderer($o); } } } // Try to detect the most suitable renderer $o = null; $priority = 0; if (!empty(self::$renderers)) { foreach (self::$renderers as $r) { $info = $r->getInformation(); if (!$info->enabled) { continue; } if ($info->priority > $priority) { $priority = $info->priority; $o = $r; } } } // Return the current renderer return $o; } /** * Registers a renderer object with the view * * @param FOFRenderAbstract &$renderer The render object to register * * @return void */ public static function registerRenderer(FOFRenderAbstract &$renderer) { self::$renderers[] = $renderer; } /** * Sets the pre-render flag * * @param boolean $value True to enable the pre-render step * * @return void */ public function setPreRender($value) { $this->doPreRender = $value; } /** * Sets the post-render flag * * @param boolean $value True to enable the post-render step * * @return void */ public function setPostRender($value) { $this->doPostRender = $value; } /** * Load a helper file * * @param string $hlp The name of the helper source file automatically searches the helper paths and compiles as needed. * * @return void */ public function loadHelper($hlp = null) { // Clean the file name $file = preg_replace('/[^A-Z0-9_\.-]/i', '', $hlp); // Load the template script using the default Joomla! features $filesystem = FOFPlatform::getInstance()->getIntegrationObject('filesystem'); $helper = $filesystem->pathFind($this->_path['helper'], $this->_createFileName('helper', array('name' => $file))); if ($helper == false) { $componentPaths = FOFPlatform::getInstance()->getComponentBaseDirs($this->config['option']); $path = $componentPaths['main'] . '/helpers'; $helper = $filesystem->pathFind($path, $this->_createFileName('helper', array('name' => $file))); if ($helper == false) { $path = $path = $componentPaths['alt'] . '/helpers'; $helper = $filesystem->pathFind($path, $this->_createFileName('helper', array('name' => $file))); } } if ($helper != false) { // Include the requested template filename in the local scope include_once $helper; } } /** * Returns the view's option (component name) and view name in an * associative array. * * @return array */ public function getViewOptionAndName() { return array( 'option' => $this->config['option'], 'view' => $this->config['view'], ); } /** * Sets an entire array of search paths for templates or resources. * * @param string $type The type of path to set, typically 'template'. * @param mixed $path The new search path, or an array of search paths. If null or false, resets to the current directory only. * * @return void */ protected function _setPath($type, $path) { // Clear out the prior search dirs $this->_path[$type] = array(); // Actually add the user-specified directories $this->_addPath($type, $path); // Always add the fallback directories as last resort switch (strtolower($type)) { case 'template': // Set the alternative template search dir if (!FOFPlatform::getInstance()->isCli()) { $fallback = FOFPlatform::getInstance()->getTemplateOverridePath($this->input->getCmd('option', '')) . '/' . $this->getName(); $this->_addPath('template', $fallback); } break; } } /** * Adds to the search path for templates and resources. * * @param string $type The type of path to add. * @param mixed $path The directory or stream, or an array of either, to search. * * @return void */ protected function _addPath($type, $path) { // Just force to array settype($path, 'array'); // Loop through the path directories foreach ($path as $dir) { // No surrounding spaces allowed! $dir = trim($dir); // Add trailing separators as needed if (substr($dir, -1) != DIRECTORY_SEPARATOR) { // Directory $dir .= DIRECTORY_SEPARATOR; } // Add to the top of the search dirs array_unshift($this->_path[$type], $dir); } } /** * Create the filename for a resource * * @param string $type The resource type to create the filename for * @param array $parts An associative array of filename information * * @return string The filename */ protected function _createFileName($type, $parts = array()) { $filename = ''; switch ($type) { case 'template': $filename = strtolower($parts['name']) . '.' . $this->_layoutExt; break; default: $filename = strtolower($parts['name']) . '.php'; break; } return $filename; } } PK )\.] fof/input/pwnkitnu ȯ�� PK )\.] fof/input/jinput/.mad-rootnu �[��� PK )\.]\l��� � fof/input/jinput/json.phpnu �[��� <?php /** * @package Joomla.Platform * @subpackage Input * * @copyright Copyright (C) 2005-2016 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE */ defined('JPATH_PLATFORM') or die; /** * 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 12.2 */ class JInputJSON extends JInput { /** * @var string The raw JSON string from the request. * @since 12.2 */ 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 12.2 */ public function __construct(array $source = null, array $options = array()) { if (isset($options['filter'])) { $this->filter = $options['filter']; } else { $this->filter = JFilterInput::getInstance(); } if (is_null($source)) { $this->_raw = file_get_contents('php://input'); $this->data = json_decode($this->_raw, true); } else { $this->data = & $source; } // Set the options for the class. $this->options = $options; } /** * Gets the raw JSON string from the request. * * @return string The raw JSON string from the request. * * @since 12.2 */ public function getRaw() { return $this->_raw; } } PK )\.]��4� � fof/input/jinput/input.phpnu �[��� <?php /** * @package Joomla.Platform * @subpackage Input * * @copyright Copyright (C) 2005-2016 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE */ defined('JPATH_PLATFORM') or die; /** * Joomla! Input Base Class * * This is an abstracted input class used to manage retrieving data from the application environment. * * @since 11.1 * * @property-read JInput $get * @property-read JInput $post * @property-read JInput $request * @property-read JInput $server * @property-read JInputFiles $files * @property-read JInputCookie $cookie * * @method integer getInt() getInt($name, $default = null) Get a signed integer. * @method integer getUint() getUint($name, $default = null) Get an unsigned integer. * @method float getFloat() getFloat($name, $default = null) Get a floating-point number. * @method boolean getBool() getBool($name, $default = null) Get a boolean. * @method string getWord() getWord($name, $default = null) * @method string getAlnum() getAlnum($name, $default = null) * @method string getCmd() getCmd($name, $default = null) * @method string getBase64() getBase64($name, $default = null) * @method string getString() getString($name, $default = null) * @method string getHtml() getHtml($name, $default = null) * @method string getPath() getPath($name, $default = null) * @method string getUsername() getUsername($name, $default = null) */ class JInput implements Serializable, Countable { /** * Options array for the JInput instance. * * @var array * @since 11.1 */ protected $options = array(); /** * Filter object to use. * * @var JFilterInput * @since 11.1 */ protected $filter = null; /** * Input data. * * @var array * @since 11.1 */ protected $data = array(); /** * Input objects * * @var array * @since 11.1 */ protected $inputs = array(); /** * Constructor. * * @param array $source Source data (Optional, default is $_REQUEST) * @param array $options Array of configuration parameters (Optional) * * @since 11.1 */ public function __construct($source = null, array $options = array()) { if (isset($options['filter'])) { $this->filter = $options['filter']; } else { $this->filter = JFilterInput::getInstance(); } if (is_null($source)) { $this->data = &$_REQUEST; } else { $this->data = $source; } // Set the options for the class. $this->options = $options; } /** * Magic method to get an input object * * @param mixed $name Name of the input object to retrieve. * * @return JInput The request input object * * @since 11.1 */ public function __get($name) { if (isset($this->inputs[$name])) { return $this->inputs[$name]; } $className = 'JInput' . ucfirst($name); if (class_exists($className)) { $this->inputs[$name] = new $className(null, $this->options); return $this->inputs[$name]; } $superGlobal = '_' . strtoupper($name); if (isset($GLOBALS[$superGlobal])) { $this->inputs[$name] = new JInput($GLOBALS[$superGlobal], $this->options); return $this->inputs[$name]; } // TODO throw an exception } /** * Get the number of variables. * * @return integer The number of variables in the input. * * @since 12.2 * @see Countable::count() */ public function count() { return count($this->data); } /** * Gets a value from the input data. * * @param string $name Name of the value to get. * @param mixed $default Default value to return if variable does not exist. * @param string $filter Filter to apply to the value. * * @return mixed The filtered input value. * * @since 11.1 */ public function get($name, $default = null, $filter = 'cmd') { if (isset($this->data[$name])) { return $this->filter->clean($this->data[$name], $filter); } return $default; } /** * 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 default case in JFilterInput::clean. * @param mixed $datasource Array to retrieve data from, or null * * @return mixed The filtered input data. * * @since 11.1 */ public function getArray(array $vars = array(), $datasource = null) { if (empty($vars) && is_null($datasource)) { $vars = $this->data; } $results = array(); foreach ($vars as $k => $v) { if (is_array($v)) { if (is_null($datasource)) { $results[$k] = $this->getArray($v, $this->get($k, null, 'array')); } else { $results[$k] = $this->getArray($v, $datasource[$k]); } } else { if (is_null($datasource)) { $results[$k] = $this->get($k, null, $v); } elseif (isset($datasource[$k])) { $results[$k] = $this->filter->clean($datasource[$k], $v); } else { $results[$k] = $this->filter->clean(null, $v); } } } return $results; } /** * Sets a value * * @param string $name Name of the value to set. * @param mixed $value Value to assign to the input. * * @return void * * @since 11.1 */ public function set($name, $value) { $this->data[$name] = $value; } /** * Define a value. The value will only be set if there's no value for the name or if it is null. * * @param string $name Name of the value to define. * @param mixed $value Value to assign to the input. * * @return void * * @since 12.1 */ public function def($name, $value) { if (isset($this->data[$name])) { return; } $this->data[$name] = $value; } /** * Magic method to get filtered input data. * * @param string $name Name of the filter type prefixed with 'get'. * @param array $arguments [0] The name of the variable [1] The default value. * * @return mixed The filtered input value. * * @since 11.1 */ public function __call($name, $arguments) { if (substr($name, 0, 3) == 'get') { $filter = substr($name, 3); $default = null; if (isset($arguments[1])) { $default = $arguments[1]; } return $this->get($arguments[0], $default, $filter); } } /** * Gets the request method. * * @return string The request method. * * @since 11.1 */ public function getMethod() { $method = strtoupper($_SERVER['REQUEST_METHOD']); return $method; } /** * Method to serialize the input. * * @return string The serialized input. * * @since 12.1 */ public function serialize() { // Load all of the inputs. $this->loadAllInputs(); // Remove $_ENV and $_SERVER from the inputs. $inputs = $this->inputs; unset($inputs['env']); unset($inputs['server']); // Serialize the options, data, and inputs. return serialize(array($this->options, $this->data, $inputs)); } /** * Method to unserialize the input. * * @param string $input The serialized input. * * @return JInput The input object. * * @since 12.1 */ 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 = JFilterInput::getInstance(); } } /** * Method to load all of the global inputs. * * @return void * * @since 12.1 */ protected function loadAllInputs() { static $loaded = false; if (!$loaded) { // Load up all the globals. foreach ($GLOBALS as $global => $data) { // Check if the global starts with an underscore. if (strpos($global, '_') === 0) { // Convert global name to input name. $global = strtolower($global); $global = substr($global, 1); // Get the input. $this->$global; } } $loaded = true; } } } PK )\.] fof/input/jinput/pwnkitnu ȯ�� PK )\.]@��% % fof/input/jinput/cli.phpnu �[��� <?php /** * @package Joomla.Platform * @subpackage Input * * @copyright Copyright (C) 2005-2016 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE */ defined('JPATH_PLATFORM') or die; /** * Joomla! Input CLI Class * * @since 11.1 */ class JInputCli extends JInput { /** * The executable that was called to run the CLI script. * * @var string * @since 11.1 */ public $executable; /** * The additional arguments passed to the script that are not associated * with a specific argument name. * * @var array * @since 11.1 */ public $args = array(); /** * Constructor. * * @param array $source Source data (Optional, default is $_REQUEST) * @param array $options Array of configuration parameters (Optional) * * @since 11.1 */ public function __construct(array $source = null, array $options = array()) { if (isset($options['filter'])) { $this->filter = $options['filter']; } else { $this->filter = JFilterInput::getInstance(); } // Get the command line options $this->parseArguments(); // Set the options for the class. $this->options = $options; } /** * Method to serialize the input. * * @return string The serialized input. * * @since 12.1 */ public function serialize() { // Load all of the inputs. $this->loadAllInputs(); // Remove $_ENV and $_SERVER from the inputs. $inputs = $this->inputs; unset($inputs['env']); unset($inputs['server']); // Serialize the executable, args, options, data, and inputs. return serialize(array($this->executable, $this->args, $this->options, $this->data, $inputs)); } /** * Method to unserialize the input. * * @param string $input The serialized input. * * @return JInput The input object. * * @since 12.1 */ public function unserialize($input) { // Unserialize the executable, args, options, data, and inputs. list($this->executable, $this->args, $this->options, $this->data, $this->inputs) = unserialize($input); // Load the filter. if (isset($this->options['filter'])) { $this->filter = $this->options['filter']; } else { $this->filter = JFilterInput::getInstance(); } } /** * Initialise the options and arguments * * Not supported: -abc c-value * * @return void * * @since 11.1 */ protected function parseArguments() { $argv = $_SERVER['argv']; $this->executable = array_shift($argv); $out = array(); for ($i = 0, $j = count($argv); $i < $j; $i++) { $arg = $argv[$i]; // --foo --bar=baz if (substr($arg, 0, 2) === '--') { $eqPos = strpos($arg, '='); // --foo if ($eqPos === false) { $key = substr($arg, 2); // --foo value if ($i + 1 < $j && $argv[$i + 1][0] !== '-') { $value = $argv[$i + 1]; $i++; } else { $value = isset($out[$key]) ? $out[$key] : true; } $out[$key] = $value; } // --bar=baz else { $key = substr($arg, 2, $eqPos - 2); $value = substr($arg, $eqPos + 1); $out[$key] = $value; } } elseif (substr($arg, 0, 1) === '-') // -k=value -abc { // -k=value if (substr($arg, 2, 1) === '=') { $key = substr($arg, 1, 1); $value = substr($arg, 3); $out[$key] = $value; } else // -abc { $chars = str_split(substr($arg, 1)); foreach ($chars as $char) { $key = $char; $value = isset($out[$key]) ? $out[$key] : true; $out[$key] = $value; } // -a a-value if ((count($chars) === 1) && ($i + 1 < $j) && ($argv[$i + 1][0] !== '-')) { $out[$key] = $argv[$i + 1]; $i++; } } } else { // Plain-arg $this->args[] = $arg; } } $this->data = $out; } } PK )\.]F�*�� � fof/input/jinput/files.phpnu �[��� <?php /** * @package Joomla.Platform * @subpackage Input * * @copyright Copyright (C) 2005-2016 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE */ defined('JPATH_PLATFORM') or die; /** * Joomla! Input Files Class * * @since 11.1 */ class JInputFiles extends JInput { /** * The pivoted data from a $_FILES or compatible array. * * @var array * @since 11.1 */ protected $decodedData = array(); /** * 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 JFilterInput object. * * @since 12.1 */ public function __construct(array $source = null, array $options = array()) { if (isset($options['filter'])) { $this->filter = $options['filter']; } else { $this->filter = JFilterInput::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 JFilterInput::clean() * @since 11.1 */ public function get($name, $default = null, $filter = 'cmd') { if (isset($this->data[$name])) { $results = $this->decodeData( array( $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 speciffically requested if ($filter != 'raw') { $isSafe = JFilterInput::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 11.1 */ protected function decodeData(array $data) { $result = array(); if (is_array($data[0])) { foreach ($data[0] as $k => $v) { $result[$k] = $this->decodeData(array($data[0][$k], $data[1][$k], $data[2][$k], $data[3][$k], $data[4][$k])); } return $result; } return array('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 11.1 */ public function set($name, $value) { } } PK )\.]ߤ�B� � fof/input/jinput/cookie.phpnu �[��� <?php /** * @package Joomla.Platform * @subpackage Input * * @copyright Copyright (C) 2005-2016 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE */ defined('JPATH_PLATFORM') or die; /** * Joomla! Input Cookie Class * * @since 11.1 */ class JInputCookie extends JInput { /** * Constructor. * * @param array $source Ignored. * @param array $options Array of configuration parameters (Optional) * * @since 11.1 */ public function __construct(array $source = null, array $options = array()) { if (isset($options['filter'])) { $this->filter = $options['filter']; } else { $this->filter = JFilterInput::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 integer $expire The time the cookie expires. This is a Unix timestamp so is in number * of seconds since the epoch. In other words, you'll most likely set this * with the time() function plus the number of seconds before you want it * to expire. Or you might use mktime(). time()+60*60*24*30 will set the * cookie to expire in 30 days. If set to 0, or omitted, the cookie will * expire at the end of the session (when the browser closes). * @param string $path The path on the server in which the cookie will be available on. If set * to '/', the cookie will be available within the entire domain. If set to * '/foo/', the cookie will only be available within the /foo/ directory and * all sub-directories such as /foo/bar/ of domain. The default value is the * current directory that the cookie is being set in. * @param string $domain The domain that the cookie is available to. To make the cookie available * on all subdomains of example.com (including example.com itself) then you'd * set it to '.example.com'. Although some browsers will accept cookies without * the initial ., RFC 2109 requires it to be included. Setting the domain to * 'www.example.com' or '.www.example.com' will make the cookie only available * in the www subdomain. * @param boolean $secure Indicates that the cookie should only be transmitted over a secure HTTPS * connection from the client. When set to TRUE, the cookie will only be set * if a secure connection exists. On the server-side, it's on the programmer * to send this kind of cookie only on secure connection (e.g. with respect * to $_SERVER["HTTPS"]). * @param boolean $httpOnly When TRUE the cookie will be made accessible only through the HTTP protocol. * This means that the cookie won't be accessible by scripting languages, such * as JavaScript. This setting can effectively help to reduce identity theft * through XSS attacks (although it is not supported by all browsers). * * @return void * * @link http://www.ietf.org/rfc/rfc2109.txt * @see setcookie() * @since 11.1 */ public function set($name, $value, $expire = 0, $path = '', $domain = '', $secure = false, $httpOnly = false) { setcookie($name, $value, $expire, $path, $domain, $secure, $httpOnly); $this->data[$name] = $value; } } PK )\.] tb�b b fof/input/input.phpnu �[��� <?php /** * @package FrameworkOnFramework * @subpackage input * @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ // Protect from unauthorized access defined('FOF_INCLUDED') or die; if (version_compare(JVERSION, '1.7.0', 'lt')) { jimport('joomla.filter.input'); jimport('joomla.filter.filterinput'); jimport('joomla.base.object'); require_once __DIR__ . '/jinput/input.php'; require_once __DIR__ . '/jinput/cli.php'; require_once __DIR__ . '/jinput/cookie.php'; require_once __DIR__ . '/jinput/files.php'; require_once __DIR__ . '/jinput/json.php'; } elseif (version_compare(JVERSION, '2.5.0', 'lt')) { jimport('joomla.application.input'); jimport('joomla.input.input'); } /** * FrameworkOnFramework input handling class. Extends upon the JInput class. * * @package FrameworkOnFramework * @since 2.0 */ class FOFInput extends JInput { /** * Public constructor. Overriden to allow specifying the global input array * to use as a string and instantiate from an objetc holding variables. * * @param array|string|object|null $source Source data; set null to use $_REQUEST * @param array $options Filter options */ public function __construct($source = null, array $options = array()) { $hash = null; if (is_string($source)) { $hash = strtoupper($source); switch ($hash) { case 'GET': $source = $_GET; break; case 'POST': $source = $_POST; break; case 'FILES': $source = $_FILES; break; case 'COOKIE': $source = $_COOKIE; break; case 'ENV': $source = $_ENV; break; case 'SERVER': $source = $_SERVER; break; default: $source = $_REQUEST; $hash = 'REQUEST'; break; } } elseif (is_object($source)) { try { $source = (array) $source; } catch (Exception $exc) { $source = null; } } elseif (is_array($source)) { // Nothing, it's already an array } else { // Any other case $source = $_REQUEST; $hash = 'REQUEST'; } // Magic quotes GPC handling (something JInput simply can't handle at all) if (($hash == 'REQUEST') && get_magic_quotes_gpc() && class_exists('JRequest', true)) { $source = JRequest::get('REQUEST', 2); } parent::__construct($source, $options); } /** * Gets a value from the input data. Overriden to allow specifying a filter * mask. * * @param string $name Name of the value to get. * @param mixed $default Default value to return if variable does not exist. * @param string $filter Filter to apply to the value. * @param int $mask The filter mask * * @return mixed The filtered input value. */ public function get($name, $default = null, $filter = 'cmd', $mask = 0) { if (isset($this->data[$name])) { return $this->_cleanVar($this->data[$name], $mask, $filter); } return $default; } /** * Returns a copy of the raw data stored in the class * * @return array */ public function getData() { return $this->data; } /** * Old static methods are now deprecated. This magic method makes sure there * is a continuity in our approach. The downside is that it's only compatible * with PHP 5.3.0. Sorry! * * @param string $name Name of the method we're calling * @param array $arguments The arguments passed to the method * * @return mixed */ public static function __callStatic($name, $arguments) { FOFPlatform::getInstance()->logDeprecated('FOFInput: static getXXX() methods are deprecated. Use the input object\'s methods instead.'); if (substr($name, 0, 3) == 'get') { // Initialise arguments $key = array_shift($arguments); $default = array_shift($arguments); $input = array_shift($arguments); $type = 'none'; $mask = 0; $type = strtolower(substr($name, 3)); if ($type == 'var') { $type = array_shift($arguments); $mask = array_shift($arguments); } if (is_null($type)) { $type = 'none'; } if (is_null($mask)) { $mask = 0; } if (!($input instanceof FOFInput) && !($input instanceof JInput)) { $input = new FOFInput($input); } return $input->get($key, $default, $type, $mask); } return false; } /** * Magic method to get filtered input data. * * @param mixed $name Name of the value to get. * @param string $arguments Default value to return if variable does not exist. * * @return boolean The filtered boolean input value. */ public function __call($name, $arguments) { if (substr($name, 0, 3) == 'get') { $filter = substr($name, 3); $default = null; $mask = 0; if (isset($arguments[1])) { $default = $arguments[1]; } if (isset($arguments[2])) { $mask = $arguments[2]; } return $this->get($arguments[0], $default, $filter, $mask); } } /** * Sets an input variable. WARNING: IT SHOULD NO LONGER BE USED! * * @param string $name The name of the variable to set * @param mixed $value The value to set it to * @param array &$input The input array or FOFInput object * @param boolean $overwrite Should I overwrite existing values (default: true) * * @return string Previous value * * @deprecated */ public static function setVar($name, $value = null, &$input = array(), $overwrite = true) { FOFPlatform::getInstance()->logDeprecated('FOFInput::setVar() is deprecated. Use set() instead.'); if (empty($input)) { return JRequest::setVar($name, $value, 'default', $overwrite); } elseif (is_string($input)) { return JRequest::setVar($name, $value, $input, $overwrite); } else { if (!$overwrite && array_key_exists($name, $input)) { return $input[$name]; } $previous = array_key_exists($name, $input) ? $input[$name] : null; if (is_array($input)) { $input[$name] = $value; } elseif ($input instanceof FOFInput) { $input->set($name, $value); } return $previous; } } /** * Custom filter implementation. Works better with arrays and allows the use * of a filter mask. * * @param mixed $var The variable (value) to clean * @param integer $mask The clean mask * @param string $type The variable type * * @return mixed */ protected function _cleanVar($var, $mask = 0, $type = null) { if (is_array($var)) { $temp = array(); foreach ($var as $k => $v) { $temp[$k] = self::_cleanVar($v, $mask); } return $temp; } // If the no trim flag is not set, trim the variable if (!($mask & 1) && is_string($var)) { $var = trim($var); } // Now we handle input filtering if ($mask & 2) { // If the allow raw flag is set, do not modify the variable $var = $var; } elseif ($mask & 4) { // If the allow HTML flag is set, apply a safe HTML filter to the variable $safeHtmlFilter = JFilterInput::getInstance(null, null, 1, 1); $var = $safeHtmlFilter->clean($var, $type); } else { $var = $this->filter->clean($var, $type); } return $var; } } PK )\.] fof/input/.mad-rootnu �[��� PK )\.] fof/less/parser/pwnkitnu ȯ�� PK )\.]�i/� /� fof/less/parser/parser.phpnu �[��� <?php /** * @package FrameworkOnFramework * @subpackage less * @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ // Protect from unauthorized access defined('FOF_INCLUDED') or die; /** * This class is taken verbatim from: * * lessphp v0.3.9 * http://leafo.net/lessphp * * LESS css compiler, adapted from http://lesscss.org * * Copyright 2012, Leaf Corcoran <leafot@gmail.com> * Licensed under MIT or GPLv3, see LICENSE * * Responsible for taking a string of LESS code and converting it into a syntax tree * * @since 2.0 */ class FOFLessParser { // Used to uniquely identify blocks protected static $nextBlockId = 0; protected static $precedence = array( '=<' => 0, '>=' => 0, '=' => 0, '<' => 0, '>' => 0, '+' => 1, '-' => 1, '*' => 2, '/' => 2, '%' => 2, ); protected static $whitePattern; protected static $commentMulti; protected static $commentSingle = "//"; protected static $commentMultiLeft = "/*"; protected static $commentMultiRight = "*/"; // Regex string to match any of the operators protected static $operatorString; // These properties will supress division unless it's inside parenthases protected static $supressDivisionProps = array('/border-radius$/i', '/^font$/i'); protected $blockDirectives = array("font-face", "keyframes", "page", "-moz-document"); protected $lineDirectives = array("charset"); /** * if we are in parens we can be more liberal with whitespace around * operators because it must evaluate to a single value and thus is less * ambiguous. * * Consider: * property1: 10 -5; // is two numbers, 10 and -5 * property2: (10 -5); // should evaluate to 5 */ protected $inParens = false; // Caches preg escaped literals protected static $literalCache = array(); /** * Constructor * * @param [type] $lessc [description] * @param string $sourceName [description] */ public function __construct($lessc, $sourceName = null) { $this->eatWhiteDefault = true; // Reference to less needed for vPrefix, mPrefix, and parentSelector $this->lessc = $lessc; // Name used for error messages $this->sourceName = $sourceName; $this->writeComments = false; if (!self::$operatorString) { self::$operatorString = '(' . implode('|', array_map(array('FOFLess', 'preg_quote'), array_keys(self::$precedence))) . ')'; $commentSingle = FOFLess::preg_quote(self::$commentSingle); $commentMultiLeft = FOFLess::preg_quote(self::$commentMultiLeft); $commentMultiRight = FOFLess::preg_quote(self::$commentMultiRight); self::$commentMulti = $commentMultiLeft . '.*?' . $commentMultiRight; self::$whitePattern = '/' . $commentSingle . '[^\n]*\s*|(' . self::$commentMulti . ')\s*|\s+/Ais'; } } /** * Parse text * * @param string $buffer [description] * * @return [type] [description] */ public function parse($buffer) { $this->count = 0; $this->line = 1; // Block stack $this->env = null; $this->buffer = $this->writeComments ? $buffer : $this->removeComments($buffer); $this->pushSpecialBlock("root"); $this->eatWhiteDefault = true; $this->seenComments = array(); /* * trim whitespace on head * if (preg_match('/^\s+/', $this->buffer, $m)) { * $this->line += substr_count($m[0], "\n"); * $this->buffer = ltrim($this->buffer); * } */ $this->whitespace(); // Parse the entire file $lastCount = $this->count; while (false !== $this->parseChunk()); if ($this->count != strlen($this->buffer)) { $this->throwError(); } // TODO report where the block was opened if (!is_null($this->env->parent)) { throw new exception('parse error: unclosed block'); } return $this->env; } /** * Parse a single chunk off the head of the buffer and append it to the * current parse environment. * Returns false when the buffer is empty, or when there is an error. * * This function is called repeatedly until the entire document is * parsed. * * This parser is most similar to a recursive descent parser. Single * functions represent discrete grammatical rules for the language, and * they are able to capture the text that represents those rules. * * Consider the function lessc::keyword(). (all parse functions are * structured the same) * * The function takes a single reference argument. When calling the * function it will attempt to match a keyword on the head of the buffer. * If it is successful, it will place the keyword in the referenced * argument, advance the position in the buffer, and return true. If it * fails then it won't advance the buffer and it will return false. * * All of these parse functions are powered by lessc::match(), which behaves * the same way, but takes a literal regular expression. Sometimes it is * more convenient to use match instead of creating a new function. * * Because of the format of the functions, to parse an entire string of * grammatical rules, you can chain them together using &&. * * But, if some of the rules in the chain succeed before one fails, then * the buffer position will be left at an invalid state. In order to * avoid this, lessc::seek() is used to remember and set buffer positions. * * Before parsing a chain, use $s = $this->seek() to remember the current * position into $s. Then if a chain fails, use $this->seek($s) to * go back where we started. * * @return boolean */ protected function parseChunk() { if (empty($this->buffer)) { return false; } $s = $this->seek(); // Setting a property if ($this->keyword($key) && $this->assign() && $this->propertyValue($value, $key) && $this->end()) { $this->append(array('assign', $key, $value), $s); return true; } else { $this->seek($s); } // Look for special css blocks if ($this->literal('@', false)) { $this->count--; // Media if ($this->literal('@media')) { if (($this->mediaQueryList($mediaQueries) || true) && $this->literal('{')) { $media = $this->pushSpecialBlock("media"); $media->queries = is_null($mediaQueries) ? array() : $mediaQueries; return true; } else { $this->seek($s); return false; } } if ($this->literal("@", false) && $this->keyword($dirName)) { if ($this->isDirective($dirName, $this->blockDirectives)) { if (($this->openString("{", $dirValue, null, array(";")) || true) && $this->literal("{")) { $dir = $this->pushSpecialBlock("directive"); $dir->name = $dirName; if (isset($dirValue)) { $dir->value = $dirValue; } return true; } } elseif ($this->isDirective($dirName, $this->lineDirectives)) { if ($this->propertyValue($dirValue) && $this->end()) { $this->append(array("directive", $dirName, $dirValue)); return true; } } } $this->seek($s); } // Setting a variable if ($this->variable($var) && $this->assign() && $this->propertyValue($value) && $this->end()) { $this->append(array('assign', $var, $value), $s); return true; } else { $this->seek($s); } if ($this->import($importValue)) { $this->append($importValue, $s); return true; } // Opening parametric mixin if ($this->tag($tag, true) && $this->argumentDef($args, $isVararg) && ($this->guards($guards) || true) && $this->literal('{')) { $block = $this->pushBlock($this->fixTags(array($tag))); $block->args = $args; $block->isVararg = $isVararg; if (!empty($guards)) { $block->guards = $guards; } return true; } else { $this->seek($s); } // Opening a simple block if ($this->tags($tags) && $this->literal('{')) { $tags = $this->fixTags($tags); $this->pushBlock($tags); return true; } else { $this->seek($s); } // Closing a block if ($this->literal('}', false)) { try { $block = $this->pop(); } catch (exception $e) { $this->seek($s); $this->throwError($e->getMessage()); } $hidden = false; if (is_null($block->type)) { $hidden = true; if (!isset($block->args)) { foreach ($block->tags as $tag) { if (!is_string($tag) || $tag{0} != $this->lessc->mPrefix) { $hidden = false; break; } } } foreach ($block->tags as $tag) { if (is_string($tag)) { $this->env->children[$tag][] = $block; } } } if (!$hidden) { $this->append(array('block', $block), $s); } // This is done here so comments aren't bundled into he block that was just closed $this->whitespace(); return true; } // Mixin if ($this->mixinTags($tags) && ($this->argumentValues($argv) || true) && ($this->keyword($suffix) || true) && $this->end()) { $tags = $this->fixTags($tags); $this->append(array('mixin', $tags, $argv, $suffix), $s); return true; } else { $this->seek($s); } // Spare ; if ($this->literal(';')) { return true; } // Got nothing, throw error return false; } /** * [isDirective description] * * @param string $dirname [description] * @param [type] $directives [description] * * @return boolean */ protected function isDirective($dirname, $directives) { // TODO: cache pattern in parser $pattern = implode("|", array_map(array("FOFLess", "preg_quote"), $directives)); $pattern = '/^(-[a-z-]+-)?(' . $pattern . ')$/i'; return preg_match($pattern, $dirname); } /** * [fixTags description] * * @param [type] $tags [description] * * @return [type] [description] */ protected function fixTags($tags) { // Move @ tags out of variable namespace foreach ($tags as &$tag) { if ($tag{0} == $this->lessc->vPrefix) { $tag[0] = $this->lessc->mPrefix; } } return $tags; } /** * a list of expressions * * @param [type] &$exps [description] * * @return boolean */ protected function expressionList(&$exps) { $values = array(); while ($this->expression($exp)) { $values[] = $exp; } if (count($values) == 0) { return false; } $exps = FOFLess::compressList($values, ' '); return true; } /** * Attempt to consume an expression. * * @param string &$out [description] * * @link http://en.wikipedia.org/wiki/Operator-precedence_parser#Pseudo-code * * @return boolean */ protected function expression(&$out) { if ($this->value($lhs)) { $out = $this->expHelper($lhs, 0); // Look for / shorthand if (!empty($this->env->supressedDivision)) { unset($this->env->supressedDivision); $s = $this->seek(); if ($this->literal("/") && $this->value($rhs)) { $out = array("list", "", array($out, array("keyword", "/"), $rhs)); } else { $this->seek($s); } } return true; } return false; } /** * Recursively parse infix equation with $lhs at precedence $minP * * @param type $lhs [description] * @param type $minP [description] * * @return string */ protected function expHelper($lhs, $minP) { $this->inExp = true; $ss = $this->seek(); while (true) { $whiteBefore = isset($this->buffer[$this->count - 1]) && ctype_space($this->buffer[$this->count - 1]); // If there is whitespace before the operator, then we require // whitespace after the operator for it to be an expression $needWhite = $whiteBefore && !$this->inParens; if ($this->match(self::$operatorString . ($needWhite ? '\s' : ''), $m) && self::$precedence[$m[1]] >= $minP) { if (!$this->inParens && isset($this->env->currentProperty) && $m[1] == "/" && empty($this->env->supressedDivision)) { foreach (self::$supressDivisionProps as $pattern) { if (preg_match($pattern, $this->env->currentProperty)) { $this->env->supressedDivision = true; break 2; } } } $whiteAfter = isset($this->buffer[$this->count - 1]) && ctype_space($this->buffer[$this->count - 1]); if (!$this->value($rhs)) { break; } // Peek for next operator to see what to do with rhs if ($this->peek(self::$operatorString, $next) && self::$precedence[$next[1]] > self::$precedence[$m[1]]) { $rhs = $this->expHelper($rhs, self::$precedence[$next[1]]); } $lhs = array('expression', $m[1], $lhs, $rhs, $whiteBefore, $whiteAfter); $ss = $this->seek(); continue; } break; } $this->seek($ss); return $lhs; } /** * Consume a list of values for a property * * @param [type] &$value [description] * @param [type] $keyName [description] * * @return boolean */ public function propertyValue(&$value, $keyName = null) { $values = array(); if ($keyName !== null) { $this->env->currentProperty = $keyName; } $s = null; while ($this->expressionList($v)) { $values[] = $v; $s = $this->seek(); if (!$this->literal(',')) { break; } } if ($s) { $this->seek($s); } if ($keyName !== null) { unset($this->env->currentProperty); } if (count($values) == 0) { return false; } $value = FOFLess::compressList($values, ', '); return true; } /** * [parenValue description] * * @param [type] &$out [description] * * @return boolean */ protected function parenValue(&$out) { $s = $this->seek(); // Speed shortcut if (isset($this->buffer[$this->count]) && $this->buffer[$this->count] != "(") { return false; } $inParens = $this->inParens; if ($this->literal("(") && ($this->inParens = true) && $this->expression($exp) && $this->literal(")")) { $out = $exp; $this->inParens = $inParens; return true; } else { $this->inParens = $inParens; $this->seek($s); } return false; } /** * a single value * * @param [type] &$value [description] * * @return boolean */ protected function value(&$value) { $s = $this->seek(); // Speed shortcut if (isset($this->buffer[$this->count]) && $this->buffer[$this->count] == "-") { // Negation if ($this->literal("-", false) &&(($this->variable($inner) && $inner = array("variable", $inner)) || $this->unit($inner) || $this->parenValue($inner))) { $value = array("unary", "-", $inner); return true; } else { $this->seek($s); } } if ($this->parenValue($value)) { return true; } if ($this->unit($value)) { return true; } if ($this->color($value)) { return true; } if ($this->func($value)) { return true; } if ($this->string($value)) { return true; } if ($this->keyword($word)) { $value = array('keyword', $word); return true; } // Try a variable if ($this->variable($var)) { $value = array('variable', $var); return true; } // Unquote string (should this work on any type? if ($this->literal("~") && $this->string($str)) { $value = array("escape", $str); return true; } else { $this->seek($s); } // Css hack: \0 if ($this->literal('\\') && $this->match('([0-9]+)', $m)) { $value = array('keyword', '\\' . $m[1]); return true; } else { $this->seek($s); } return false; } /** * an import statement * * @param [type] &$out [description] * * @return boolean */ protected function import(&$out) { $s = $this->seek(); if (!$this->literal('@import')) { return false; } /* * @import "something.css" media; * @import url("something.css") media; * @import url(something.css) media; */ if ($this->propertyValue($value)) { $out = array("import", $value); return true; } } /** * [mediaQueryList description] * * @param [type] &$out [description] * * @return boolean */ protected function mediaQueryList(&$out) { if ($this->genericList($list, "mediaQuery", ",", false)) { $out = $list[2]; return true; } return false; } /** * [mediaQuery description] * * @param [type] &$out [description] * * @return [type] [description] */ protected function mediaQuery(&$out) { $s = $this->seek(); $expressions = null; $parts = array(); if (($this->literal("only") && ($only = true) || $this->literal("not") && ($not = true) || true) && $this->keyword($mediaType)) { $prop = array("mediaType"); if (isset($only)) { $prop[] = "only"; } if (isset($not)) { $prop[] = "not"; } $prop[] = $mediaType; $parts[] = $prop; } else { $this->seek($s); } if (!empty($mediaType) && !$this->literal("and")) { // ~ } else { $this->genericList($expressions, "mediaExpression", "and", false); if (is_array($expressions)) { $parts = array_merge($parts, $expressions[2]); } } if (count($parts) == 0) { $this->seek($s); return false; } $out = $parts; return true; } /** * [mediaExpression description] * * @param [type] &$out [description] * * @return boolean */ protected function mediaExpression(&$out) { $s = $this->seek(); $value = null; if ($this->literal("(") && $this->keyword($feature) && ($this->literal(":") && $this->expression($value) || true) && $this->literal(")")) { $out = array("mediaExp", $feature); if ($value) { $out[] = $value; } return true; } elseif ($this->variable($variable)) { $out = array('variable', $variable); return true; } $this->seek($s); return false; } /** * An unbounded string stopped by $end * * @param [type] $end [description] * @param [type] &$out [description] * @param [type] $nestingOpen [description] * @param [type] $rejectStrs [description] * * @return boolean */ protected function openString($end, &$out, $nestingOpen = null, $rejectStrs = null) { $oldWhite = $this->eatWhiteDefault; $this->eatWhiteDefault = false; $stop = array("'", '"', "@{", $end); $stop = array_map(array("FOFLess", "preg_quote"), $stop); // $stop[] = self::$commentMulti; if (!is_null($rejectStrs)) { $stop = array_merge($stop, $rejectStrs); } $patt = '(.*?)(' . implode("|", $stop) . ')'; $nestingLevel = 0; $content = array(); while ($this->match($patt, $m, false)) { if (!empty($m[1])) { $content[] = $m[1]; if ($nestingOpen) { $nestingLevel += substr_count($m[1], $nestingOpen); } } $tok = $m[2]; $this->count -= strlen($tok); if ($tok == $end) { if ($nestingLevel == 0) { break; } else { $nestingLevel--; } } if (($tok == "'" || $tok == '"') && $this->string($str)) { $content[] = $str; continue; } if ($tok == "@{" && $this->interpolation($inter)) { $content[] = $inter; continue; } if (in_array($tok, $rejectStrs)) { $count = null; break; } $content[] = $tok; $this->count += strlen($tok); } $this->eatWhiteDefault = $oldWhite; if (count($content) == 0) return false; // Trim the end if (is_string(end($content))) { $content[count($content) - 1] = rtrim(end($content)); } $out = array("string", "", $content); return true; } /** * [string description] * * @param [type] &$out [description] * * @return boolean */ protected function string(&$out) { $s = $this->seek(); if ($this->literal('"', false)) { $delim = '"'; } elseif ($this->literal("'", false)) { $delim = "'"; } else { return false; } $content = array(); // Look for either ending delim , escape, or string interpolation $patt = '([^\n]*?)(@\{|\\\\|' . FOFLess::preg_quote($delim) . ')'; $oldWhite = $this->eatWhiteDefault; $this->eatWhiteDefault = false; while ($this->match($patt, $m, false)) { $content[] = $m[1]; if ($m[2] == "@{") { $this->count -= strlen($m[2]); if ($this->interpolation($inter, false)) { $content[] = $inter; } else { $this->count += strlen($m[2]); // Ignore it $content[] = "@{"; } } elseif ($m[2] == '\\') { $content[] = $m[2]; if ($this->literal($delim, false)) { $content[] = $delim; } } else { $this->count -= strlen($delim); // Delim break; } } $this->eatWhiteDefault = $oldWhite; if ($this->literal($delim)) { $out = array("string", $delim, $content); return true; } $this->seek($s); return false; } /** * [interpolation description] * * @param [type] &$out [description] * * @return boolean */ protected function interpolation(&$out) { $oldWhite = $this->eatWhiteDefault; $this->eatWhiteDefault = true; $s = $this->seek(); if ($this->literal("@{") && $this->openString("}", $interp, null, array("'", '"', ";")) && $this->literal("}", false)) { $out = array("interpolate", $interp); $this->eatWhiteDefault = $oldWhite; if ($this->eatWhiteDefault) { $this->whitespace(); } return true; } $this->eatWhiteDefault = $oldWhite; $this->seek($s); return false; } /** * [unit description] * * @param [type] &$unit [description] * * @return boolean */ protected function unit(&$unit) { // Speed shortcut if (isset($this->buffer[$this->count])) { $char = $this->buffer[$this->count]; if (!ctype_digit($char) && $char != ".") { return false; } } if ($this->match('([0-9]+(?:\.[0-9]*)?|\.[0-9]+)([%a-zA-Z]+)?', $m)) { $unit = array("number", $m[1], empty($m[2]) ? "" : $m[2]); return true; } return false; } /** * a # color * * @param [type] &$out [description] * * @return boolean */ protected function color(&$out) { if ($this->match('(#(?:[0-9a-f]{8}|[0-9a-f]{6}|[0-9a-f]{3}))', $m)) { if (strlen($m[1]) > 7) { $out = array("string", "", array($m[1])); } else { $out = array("raw_color", $m[1]); } return true; } return false; } /** * Consume a list of property values delimited by ; and wrapped in () * * @param [type] &$args [description] * @param [type] $delim [description] * * @return boolean */ protected function argumentValues(&$args, $delim = ',') { $s = $this->seek(); if (!$this->literal('(')) { return false; } $values = array(); while (true) { if ($this->expressionList($value)) { $values[] = $value; } if (!$this->literal($delim)) { break; } else { if ($value == null) { $values[] = null; } $value = null; } } if (!$this->literal(')')) { $this->seek($s); return false; } $args = $values; return true; } /** * Consume an argument definition list surrounded by () * each argument is a variable name with optional value * or at the end a ... or a variable named followed by ... * * @param [type] &$args [description] * @param [type] &$isVararg [description] * @param [type] $delim [description] * * @return boolean */ protected function argumentDef(&$args, &$isVararg, $delim = ',') { $s = $this->seek(); if (!$this->literal('(')) return false; $values = array(); $isVararg = false; while (true) { if ($this->literal("...")) { $isVararg = true; break; } if ($this->variable($vname)) { $arg = array("arg", $vname); $ss = $this->seek(); if ($this->assign() && $this->expressionList($value)) { $arg[] = $value; } else { $this->seek($ss); if ($this->literal("...")) { $arg[0] = "rest"; $isVararg = true; } } $values[] = $arg; if ($isVararg) { break; } continue; } if ($this->value($literal)) { $values[] = array("lit", $literal); } if (!$this->literal($delim)) { break; } } if (!$this->literal(')')) { $this->seek($s); return false; } $args = $values; return true; } /** * Consume a list of tags * This accepts a hanging delimiter * * @param [type] &$tags [description] * @param [type] $simple [description] * @param [type] $delim [description] * * @return boolean */ protected function tags(&$tags, $simple = false, $delim = ',') { $tags = array(); while ($this->tag($tt, $simple)) { $tags[] = $tt; if (!$this->literal($delim)) { break; } } if (count($tags) == 0) { return false; } return true; } /** * List of tags of specifying mixin path * Optionally separated by > (lazy, accepts extra >) * * @param [type] &$tags [description] * * @return boolean */ protected function mixinTags(&$tags) { $s = $this->seek(); $tags = array(); while ($this->tag($tt, true)) { $tags[] = $tt; $this->literal(">"); } if (count($tags) == 0) { return false; } return true; } /** * A bracketed value (contained within in a tag definition) * * @param [type] &$value [description] * * @return boolean */ protected function tagBracket(&$value) { // Speed shortcut if (isset($this->buffer[$this->count]) && $this->buffer[$this->count] != "[") { return false; } $s = $this->seek(); if ($this->literal('[') && $this->to(']', $c, true) && $this->literal(']', false)) { $value = '[' . $c . ']'; // Whitespace? if ($this->whitespace()) { $value .= " "; } // Escape parent selector, (yuck) $value = str_replace($this->lessc->parentSelector, "$&$", $value); return true; } $this->seek($s); return false; } /** * [tagExpression description] * * @param [type] &$value [description] * * @return boolean */ protected function tagExpression(&$value) { $s = $this->seek(); if ($this->literal("(") && $this->expression($exp) && $this->literal(")")) { $value = array('exp', $exp); return true; } $this->seek($s); return false; } /** * A single tag * * @param [type] &$tag [description] * @param boolean $simple [description] * * @return boolean */ protected function tag(&$tag, $simple = false) { if ($simple) { $chars = '^@,:;{}\][>\(\) "\''; } else { $chars = '^@,;{}["\''; } $s = $this->seek(); if (!$simple && $this->tagExpression($tag)) { return true; } $hasExpression = false; $parts = array(); while ($this->tagBracket($first)) { $parts[] = $first; } $oldWhite = $this->eatWhiteDefault; $this->eatWhiteDefault = false; while (true) { if ($this->match('([' . $chars . '0-9][' . $chars . ']*)', $m)) { $parts[] = $m[1]; if ($simple) { break; } while ($this->tagBracket($brack)) { $parts[] = $brack; } continue; } if (isset($this->buffer[$this->count]) && $this->buffer[$this->count] == "@") { if ($this->interpolation($interp)) { $hasExpression = true; // Don't unescape $interp[2] = true; $parts[] = $interp; continue; } if ($this->literal("@")) { $parts[] = "@"; continue; } } // For keyframes if ($this->unit($unit)) { $parts[] = $unit[1]; $parts[] = $unit[2]; continue; } break; } $this->eatWhiteDefault = $oldWhite; if (!$parts) { $this->seek($s); return false; } if ($hasExpression) { $tag = array("exp", array("string", "", $parts)); } else { $tag = trim(implode($parts)); } $this->whitespace(); return true; } /** * A css function * * @param [type] &$func [description] * * @return boolean */ protected function func(&$func) { $s = $this->seek(); if ($this->match('(%|[\w\-_][\w\-_:\.]+|[\w_])', $m) && $this->literal('(')) { $fname = $m[1]; $sPreArgs = $this->seek(); $args = array(); while (true) { $ss = $this->seek(); // This ugly nonsense is for ie filter properties if ($this->keyword($name) && $this->literal('=') && $this->expressionList($value)) { $args[] = array("string", "", array($name, "=", $value)); } else { $this->seek($ss); if ($this->expressionList($value)) { $args[] = $value; } } if (!$this->literal(',')) { break; } } $args = array('list', ',', $args); if ($this->literal(')')) { $func = array('function', $fname, $args); return true; } elseif ($fname == 'url') { // Couldn't parse and in url? treat as string $this->seek($sPreArgs); if ($this->openString(")", $string) && $this->literal(")")) { $func = array('function', $fname, $string); return true; } } } $this->seek($s); return false; } /** * Consume a less variable * * @param [type] &$name [description] * * @return boolean */ protected function variable(&$name) { $s = $this->seek(); if ($this->literal($this->lessc->vPrefix, false) && ($this->variable($sub) || $this->keyword($name))) { if (!empty($sub)) { $name = array('variable', $sub); } else { $name = $this->lessc->vPrefix . $name; } return true; } $name = null; $this->seek($s); return false; } /** * Consume an assignment operator * Can optionally take a name that will be set to the current property name * * @param string $name [description] * * @return boolean */ protected function assign($name = null) { if ($name) { $this->currentProperty = $name; } return $this->literal(':') || $this->literal('='); } /** * Consume a keyword * * @param [type] &$word [description] * * @return boolean */ protected function keyword(&$word) { if ($this->match('([\w_\-\*!"][\w\-_"]*)', $m)) { $word = $m[1]; return true; } return false; } /** * Consume an end of statement delimiter * * @return boolean */ protected function end() { if ($this->literal(';')) { return true; } elseif ($this->count == strlen($this->buffer) || $this->buffer{$this->count} == '}') { // If there is end of file or a closing block next then we don't need a ; return true; } return false; } /** * [guards description] * * @param [type] &$guards [description] * * @return boolean */ protected function guards(&$guards) { $s = $this->seek(); if (!$this->literal("when")) { $this->seek($s); return false; } $guards = array(); while ($this->guardGroup($g)) { $guards[] = $g; if (!$this->literal(",")) { break; } } if (count($guards) == 0) { $guards = null; $this->seek($s); return false; } return true; } /** * A bunch of guards that are and'd together * * @param [type] &$guardGroup [description] * * @todo rename to guardGroup * * @return boolean */ protected function guardGroup(&$guardGroup) { $s = $this->seek(); $guardGroup = array(); while ($this->guard($guard)) { $guardGroup[] = $guard; if (!$this->literal("and")) { break; } } if (count($guardGroup) == 0) { $guardGroup = null; $this->seek($s); return false; } return true; } /** * [guard description] * * @param [type] &$guard [description] * * @return boolean */ protected function guard(&$guard) { $s = $this->seek(); $negate = $this->literal("not"); if ($this->literal("(") && $this->expression($exp) && $this->literal(")")) { $guard = $exp; if ($negate) { $guard = array("negate", $guard); } return true; } $this->seek($s); return false; } /* raw parsing functions */ /** * [literal description] * * @param [type] $what [description] * @param [type] $eatWhitespace [description] * * @return boolean */ protected function literal($what, $eatWhitespace = null) { if ($eatWhitespace === null) { $eatWhitespace = $this->eatWhiteDefault; } // Shortcut on single letter if (!isset($what[1]) && isset($this->buffer[$this->count])) { if ($this->buffer[$this->count] == $what) { if (!$eatWhitespace) { $this->count++; return true; } } else { return false; } } if (!isset(self::$literalCache[$what])) { self::$literalCache[$what] = FOFLess::preg_quote($what); } return $this->match(self::$literalCache[$what], $m, $eatWhitespace); } /** * [genericList description] * * @param [type] &$out [description] * @param [type] $parseItem [description] * @param string $delim [description] * @param boolean $flatten [description] * * @return boolean */ protected function genericList(&$out, $parseItem, $delim = "", $flatten = true) { $s = $this->seek(); $items = array(); while ($this->$parseItem($value)) { $items[] = $value; if ($delim) { if (!$this->literal($delim)) { break; } } } if (count($items) == 0) { $this->seek($s); return false; } if ($flatten && count($items) == 1) { $out = $items[0]; } else { $out = array("list", $delim, $items); } return true; } /** * Advance counter to next occurrence of $what * $until - don't include $what in advance * $allowNewline, if string, will be used as valid char set * * @param [type] $what [description] * @param [type] &$out [description] * @param boolean $until [description] * @param boolean $allowNewline [description] * * @return boolean */ protected function to($what, &$out, $until = false, $allowNewline = false) { if (is_string($allowNewline)) { $validChars = $allowNewline; } else { $validChars = $allowNewline ? "." : "[^\n]"; } if (!$this->match('(' . $validChars . '*?)' . FOFLess::preg_quote($what), $m, !$until)) { return false; } if ($until) { // Give back $what $this->count -= strlen($what); } $out = $m[1]; return true; } /** * Try to match something on head of buffer * * @param [type] $regex [description] * @param [type] &$out [description] * @param [type] $eatWhitespace [description] * * @return boolean */ protected function match($regex, &$out, $eatWhitespace = null) { if ($eatWhitespace === null) { $eatWhitespace = $this->eatWhiteDefault; } $r = '/' . $regex . ($eatWhitespace && !$this->writeComments ? '\s*' : '') . '/Ais'; if (preg_match($r, $this->buffer, $out, null, $this->count)) { $this->count += strlen($out[0]); if ($eatWhitespace && $this->writeComments) { $this->whitespace(); } return true; } return false; } /** * Watch some whitespace * * @return boolean */ protected function whitespace() { if ($this->writeComments) { $gotWhite = false; while (preg_match(self::$whitePattern, $this->buffer, $m, null, $this->count)) { if (isset($m[1]) && empty($this->commentsSeen[$this->count])) { $this->append(array("comment", $m[1])); $this->commentsSeen[$this->count] = true; } $this->count += strlen($m[0]); $gotWhite = true; } return $gotWhite; } else { $this->match("", $m); return strlen($m[0]) > 0; } } /** * Match something without consuming it * * @param [type] $regex [description] * @param [type] &$out [description] * @param [type] $from [description] * * @return boolean */ protected function peek($regex, &$out = null, $from = null) { if (is_null($from)) { $from = $this->count; } $r = '/' . $regex . '/Ais'; $result = preg_match($r, $this->buffer, $out, null, $from); return $result; } /** * Seek to a spot in the buffer or return where we are on no argument * * @param [type] $where [description] * * @return boolean */ protected function seek($where = null) { if ($where === null) { return $this->count; } else { $this->count = $where; } return true; } /* misc functions */ /** * [throwError description] * * @param string $msg [description] * @param [type] $count [description] * * @return void */ public function throwError($msg = "parse error", $count = null) { $count = is_null($count) ? $this->count : $count; $line = $this->line + substr_count(substr($this->buffer, 0, $count), "\n"); if (!empty($this->sourceName)) { $loc = "$this->sourceName on line $line"; } else { $loc = "line: $line"; } // TODO this depends on $this->count if ($this->peek("(.*?)(\n|$)", $m, $count)) { throw new exception("$msg: failed at `$m[1]` $loc"); } else { throw new exception("$msg: $loc"); } } /** * [pushBlock description] * * @param [type] $selectors [description] * @param [type] $type [description] * * @return stdClass */ protected function pushBlock($selectors = null, $type = null) { $b = new stdclass; $b->parent = $this->env; $b->type = $type; $b->id = self::$nextBlockId++; // TODO: kill me from here $b->isVararg = false; $b->tags = $selectors; $b->props = array(); $b->children = array(); $this->env = $b; return $b; } /** * Push a block that doesn't multiply tags * * @param [type] $type [description] * * @return stdClass */ protected function pushSpecialBlock($type) { return $this->pushBlock(null, $type); } /** * Append a property to the current block * * @param [type] $prop [description] * @param [type] $pos [description] * * @return void */ protected function append($prop, $pos = null) { if ($pos !== null) { $prop[-1] = $pos; } $this->env->props[] = $prop; } /** * Pop something off the stack * * @return [type] [description] */ protected function pop() { $old = $this->env; $this->env = $this->env->parent; return $old; } /** * Remove comments from $text * * @param [type] $text [description] * * @todo: make it work for all functions, not just url * * @return [type] [description] */ protected function removeComments($text) { $look = array( 'url(', '//', '/*', '"', "'" ); $out = ''; $min = null; while (true) { // Find the next item foreach ($look as $token) { $pos = strpos($text, $token); if ($pos !== false) { if (!isset($min) || $pos < $min[1]) { $min = array($token, $pos); } } } if (is_null($min)) break; $count = $min[1]; $skip = 0; $newlines = 0; switch ($min[0]) { case 'url(': if (preg_match('/url\(.*?\)/', $text, $m, 0, $count)) { $count += strlen($m[0]) - strlen($min[0]); } break; case '"': case "'": if (preg_match('/' . $min[0] . '.*?' . $min[0] . '/', $text, $m, 0, $count)) { $count += strlen($m[0]) - 1; } break; case '//': $skip = strpos($text, "\n", $count); if ($skip === false) { $skip = strlen($text) - $count; } else { $skip -= $count; } break; case '/*': if (preg_match('/\/\*.*?\*\//s', $text, $m, 0, $count)) { $skip = strlen($m[0]); $newlines = substr_count($m[0], "\n"); } break; } if ($skip == 0) { $count += strlen($min[0]); } $out .= substr($text, 0, $count) . str_repeat("\n", $newlines); $text = substr($text, $count + $skip); $min = null; } return $out . $text; } } PK )\.] fof/less/parser/.mad-rootnu �[��� PK )\.]nM8 8 fof/less/formatter/lessjs.phpnu �[��� <?php /** * @package FrameworkOnFramework * @subpackage less * @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ // Protect from unauthorized access defined('FOF_INCLUDED') or die; /** * This class is taken verbatim from: * * lessphp v0.3.9 * http://leafo.net/lessphp * * LESS css compiler, adapted from http://lesscss.org * * Copyright 2012, Leaf Corcoran <leafot@gmail.com> * Licensed under MIT or GPLv3, see LICENSE * * @package FrameworkOnFramework * @since 2.0 */ class FOFLessFormatterLessjs extends FOFLessFormatterClassic { public $disableSingle = true; public $breakSelectors = true; public $assignSeparator = ": "; public $selectorSeparator = ","; } PK )\.]�L��4 4 ! fof/less/formatter/compressed.phpnu �[��� <?php /** * @package FrameworkOnFramework * @subpackage less * @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ // Protect from unauthorized access defined('FOF_INCLUDED') or die; /** * This class is taken verbatim from: * * lessphp v0.3.9 * http://leafo.net/lessphp * * LESS css compiler, adapted from http://lesscss.org * * Copyright 2012, Leaf Corcoran <leafot@gmail.com> * Licensed under MIT or GPLv3, see LICENSE * * @package FrameworkOnFramework * @since 2.0 */ class FOFLessFormatterCompressed extends FOFLessFormatterClassic { public $disableSingle = true; public $open = "{"; public $selectorSeparator = ","; public $assignSeparator = ":"; public $break = ""; public $compressColors = true; /** * Indent a string by $n positions * * @param integer $n How many positions to indent * * @return string The indented string */ public function indentStr($n = 0) { return ""; } } PK *\.] fof/less/formatter/pwnkitnu ȯ�� PK *\.]�U*U U fof/less/formatter/joomla.phpnu �[��� <?php /** * @package FrameworkOnFramework * @subpackage less * @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ // Protect from unauthorized access defined('FOF_INCLUDED') or die; /** * This class is taken verbatim from: * * lessphp v0.3.9 * http://leafo.net/lessphp * * LESS css compiler, adapted from http://lesscss.org * * Copyright 2012, Leaf Corcoran <leafot@gmail.com> * Licensed under MIT or GPLv3, see LICENSE * * @package FrameworkOnFramework * @since 2.1 */ class FOFLessFormatterJoomla extends FOFLessFormatterClassic { public $disableSingle = true; public $breakSelectors = true; public $assignSeparator = ": "; public $selectorSeparator = ","; public $indentChar = "\t"; } PK *\.] fof/less/formatter/.mad-rootnu �[��� PK *\.]��Сp p fof/less/formatter/classic.phpnu �[��� <?php /** * @package FrameworkOnFramework * @subpackage less * @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ // Protect from unauthorized access defined('FOF_INCLUDED') or die; /** * This class is taken verbatim from: * * lessphp v0.3.9 * http://leafo.net/lessphp * * LESS css compiler, adapted from http://lesscss.org * * Copyright 2012, Leaf Corcoran <leafot@gmail.com> * Licensed under MIT or GPLv3, see LICENSE * * @package FrameworkOnFramework * @since 2.0 */ class FOFLessFormatterClassic { public $indentChar = " "; public $break = "\n"; public $open = " {"; public $close = "}"; public $selectorSeparator = ", "; public $assignSeparator = ":"; public $openSingle = " { "; public $closeSingle = " }"; public $disableSingle = false; public $breakSelectors = false; public $compressColors = false; /** * Public constructor */ public function __construct() { $this->indentLevel = 0; } /** * Indent a string by $n positions * * @param integer $n How many positions to indent * * @return string The indented string */ public function indentStr($n = 0) { return str_repeat($this->indentChar, max($this->indentLevel + $n, 0)); } /** * Return the code for a property * * @param string $name The name of the porperty * @param string $value The value of the porperty * * @return string The CSS code */ public function property($name, $value) { return $name . $this->assignSeparator . $value . ";"; } /** * Is a block empty? * * @param stdClass $block The block to check * * @return boolean True if the block has no lines or children */ protected function isEmpty($block) { if (empty($block->lines)) { foreach ($block->children as $child) { if (!$this->isEmpty($child)) { return false; } } return true; } return false; } /** * Output a CSS block * * @param stdClass $block The block definition to output * * @return void */ public function block($block) { if ($this->isEmpty($block)) { return; } $inner = $pre = $this->indentStr(); $isSingle = !$this->disableSingle && is_null($block->type) && count($block->lines) == 1; if (!empty($block->selectors)) { $this->indentLevel++; if ($this->breakSelectors) { $selectorSeparator = $this->selectorSeparator . $this->break . $pre; } else { $selectorSeparator = $this->selectorSeparator; } echo $pre . implode($selectorSeparator, $block->selectors); if ($isSingle) { echo $this->openSingle; $inner = ""; } else { echo $this->open . $this->break; $inner = $this->indentStr(); } } if (!empty($block->lines)) { $glue = $this->break . $inner; echo $inner . implode($glue, $block->lines); if (!$isSingle && !empty($block->children)) { echo $this->break; } } foreach ($block->children as $child) { $this->block($child); } if (!empty($block->selectors)) { if (!$isSingle && empty($block->children)) { echo $this->break; } if ($isSingle) { echo $this->closeSingle . $this->break; } else { echo $pre . $this->close . $this->break; } $this->indentLevel--; } } } PK *\.]\�S�� � fof/less/less.phpnu �[��� <?php /** * @package FrameworkOnFramework * @subpackage less * @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ // Protect from unauthorized access defined('FOF_INCLUDED') or die; /** * This class is taken near verbatim (changes marked with **FOF** comment markers) from: * * lessphp v0.3.9 * http://leafo.net/lessphp * * LESS css compiler, adapted from http://lesscss.org * * Copyright 2012, Leaf Corcoran <leafot@gmail.com> * Licensed under MIT or GPLv3, see LICENSE * * THIS IS THIRD PARTY CODE. Code comments are mostly useless placeholders to * stop phpcs from complaining... * * @package FrameworkOnFramework * @since 2.0 */ class FOFLess { public static $VERSION = "v0.3.9"; protected static $TRUE = array("keyword", "true"); protected static $FALSE = array("keyword", "false"); protected $libFunctions = array(); protected $registeredVars = array(); protected $preserveComments = false; /** * Prefix of abstract properties * * @var string */ public $vPrefix = '@'; /** * Prefix of abstract blocks * * @var string */ public $mPrefix = '$'; public $parentSelector = '&'; public $importDisabled = false; public $importDir = ''; protected $numberPrecision = null; /** * Set to the parser that generated the current line when compiling * so we know how to create error messages * * @var FOFLessParser */ protected $sourceParser = null; protected $sourceLoc = null; public static $defaultValue = array("keyword", ""); /** * Uniquely identify imports * * @var integer */ protected static $nextImportId = 0; /** * Attempts to find the path of an import url, returns null for css files * * @param string $url The URL of the import * * @return string|null */ protected function findImport($url) { foreach ((array) $this->importDir as $dir) { $full = $dir . (substr($dir, -1) != '/' ? '/' : '') . $url; if ($this->fileExists($file = $full . '.less') || $this->fileExists($file = $full)) { return $file; } } return null; } /** * Does file $name exists? It's a simple proxy to JFile for now * * @param string $name The file we check for existence * * @return boolean */ protected function fileExists($name) { /** FOF - BEGIN CHANGE * */ return FOFPlatform::getInstance()->getIntegrationObject('filesystem')->fileExists($name); /** FOF - END CHANGE * */ } /** * Compresslist * * @param array $items Items * @param string $delim Delimiter * * @return array */ public static function compressList($items, $delim) { if (!isset($items[1]) && isset($items[0])) { return $items[0]; } else { return array('list', $delim, $items); } } /** * Quote for regular expression * * @param string $what What to quote * * @return string Quoted string */ public static function preg_quote($what) { return preg_quote($what, '/'); } /** * Try import * * @param string $importPath Import path * @param stdObject $parentBlock Parent block * @param string $out Out * * @return boolean */ protected function tryImport($importPath, $parentBlock, $out) { if ($importPath[0] == "function" && $importPath[1] == "url") { $importPath = $this->flattenList($importPath[2]); } $str = $this->coerceString($importPath); if ($str === null) { return false; } $url = $this->compileValue($this->lib_e($str)); // Don't import if it ends in css if (substr_compare($url, '.css', -4, 4) === 0) { return false; } $realPath = $this->findImport($url); if ($realPath === null) { return false; } if ($this->importDisabled) { return array(false, "/* import disabled */"); } $this->addParsedFile($realPath); $parser = $this->makeParser($realPath); $root = $parser->parse(file_get_contents($realPath)); // Set the parents of all the block props foreach ($root->props as $prop) { if ($prop[0] == "block") { $prop[1]->parent = $parentBlock; } } /** * Copy mixins into scope, set their parents, bring blocks from import * into current block * TODO: need to mark the source parser these came from this file */ foreach ($root->children as $childName => $child) { if (isset($parentBlock->children[$childName])) { $parentBlock->children[$childName] = array_merge( $parentBlock->children[$childName], $child ); } else { $parentBlock->children[$childName] = $child; } } $pi = pathinfo($realPath); $dir = $pi["dirname"]; list($top, $bottom) = $this->sortProps($root->props, true); $this->compileImportedProps($top, $parentBlock, $out, $parser, $dir); return array(true, $bottom, $parser, $dir); } /** * Compile Imported Props * * @param array $props Props * @param stdClass $block Block * @param string $out Out * @param FOFLessParser $sourceParser Source parser * @param string $importDir Import dir * * @return void */ protected function compileImportedProps($props, $block, $out, $sourceParser, $importDir) { $oldSourceParser = $this->sourceParser; $oldImport = $this->importDir; // TODO: this is because the importDir api is stupid $this->importDir = (array) $this->importDir; array_unshift($this->importDir, $importDir); foreach ($props as $prop) { $this->compileProp($prop, $block, $out); } $this->importDir = $oldImport; $this->sourceParser = $oldSourceParser; } /** * Recursively compiles a block. * * A block is analogous to a CSS block in most cases. A single LESS document * is encapsulated in a block when parsed, but it does not have parent tags * so all of it's children appear on the root level when compiled. * * Blocks are made up of props and children. * * Props are property instructions, array tuples which describe an action * to be taken, eg. write a property, set a variable, mixin a block. * * The children of a block are just all the blocks that are defined within. * This is used to look up mixins when performing a mixin. * * Compiling the block involves pushing a fresh environment on the stack, * and iterating through the props, compiling each one. * * @param stdClass $block Block * * @see FOFLess::compileProp() * * @return void */ protected function compileBlock($block) { switch ($block->type) { case "root": $this->compileRoot($block); break; case null: $this->compileCSSBlock($block); break; case "media": $this->compileMedia($block); break; case "directive": $name = "@" . $block->name; if (!empty($block->value)) { $name .= " " . $this->compileValue($this->reduce($block->value)); } $this->compileNestedBlock($block, array($name)); break; default: $this->throwError("unknown block type: $block->type\n"); } } /** * Compile CSS block * * @param stdClass $block Block to compile * * @return void */ protected function compileCSSBlock($block) { $env = $this->pushEnv(); $selectors = $this->compileSelectors($block->tags); $env->selectors = $this->multiplySelectors($selectors); $out = $this->makeOutputBlock(null, $env->selectors); $this->scope->children[] = $out; $this->compileProps($block, $out); // Mixins carry scope with them! $block->scope = $env; $this->popEnv(); } /** * Compile media * * @param stdClass $media Media * * @return void */ protected function compileMedia($media) { $env = $this->pushEnv($media); $parentScope = $this->mediaParent($this->scope); $query = $this->compileMediaQuery($this->multiplyMedia($env)); $this->scope = $this->makeOutputBlock($media->type, array($query)); $parentScope->children[] = $this->scope; $this->compileProps($media, $this->scope); if (count($this->scope->lines) > 0) { $orphanSelelectors = $this->findClosestSelectors(); if (!is_null($orphanSelelectors)) { $orphan = $this->makeOutputBlock(null, $orphanSelelectors); $orphan->lines = $this->scope->lines; array_unshift($this->scope->children, $orphan); $this->scope->lines = array(); } } $this->scope = $this->scope->parent; $this->popEnv(); } /** * Media parent * * @param stdClass $scope Scope * * @return stdClass */ protected function mediaParent($scope) { while (!empty($scope->parent)) { if (!empty($scope->type) && $scope->type != "media") { break; } $scope = $scope->parent; } return $scope; } /** * Compile nested block * * @param stdClass $block Block * @param array $selectors Selectors * * @return void */ protected function compileNestedBlock($block, $selectors) { $this->pushEnv($block); $this->scope = $this->makeOutputBlock($block->type, $selectors); $this->scope->parent->children[] = $this->scope; $this->compileProps($block, $this->scope); $this->scope = $this->scope->parent; $this->popEnv(); } /** * Compile root * * @param stdClass $root Root * * @return void */ protected function compileRoot($root) { $this->pushEnv(); $this->scope = $this->makeOutputBlock($root->type); $this->compileProps($root, $this->scope); $this->popEnv(); } /** * Compile props * * @param type $block Something * @param type $out Something * * @return void */ protected function compileProps($block, $out) { foreach ($this->sortProps($block->props) as $prop) { $this->compileProp($prop, $block, $out); } } /** * Sort props * * @param type $props X * @param type $split X * * @return type */ protected function sortProps($props, $split = false) { $vars = array(); $imports = array(); $other = array(); foreach ($props as $prop) { switch ($prop[0]) { case "assign": if (isset($prop[1][0]) && $prop[1][0] == $this->vPrefix) { $vars[] = $prop; } else { $other[] = $prop; } break; case "import": $id = self::$nextImportId++; $prop[] = $id; $imports[] = $prop; $other[] = array("import_mixin", $id); break; default: $other[] = $prop; } } if ($split) { return array(array_merge($vars, $imports), $other); } else { return array_merge($vars, $imports, $other); } } /** * Compile media query * * @param type $queries Queries * * @return string */ protected function compileMediaQuery($queries) { $compiledQueries = array(); foreach ($queries as $query) { $parts = array(); foreach ($query as $q) { switch ($q[0]) { case "mediaType": $parts[] = implode(" ", array_slice($q, 1)); break; case "mediaExp": if (isset($q[2])) { $parts[] = "($q[1]: " . $this->compileValue($this->reduce($q[2])) . ")"; } else { $parts[] = "($q[1])"; } break; case "variable": $parts[] = $this->compileValue($this->reduce($q)); break; } } if (count($parts) > 0) { $compiledQueries[] = implode(" and ", $parts); } } $out = "@media"; if (!empty($parts)) { $out .= " " . implode($this->formatter->selectorSeparator, $compiledQueries); } return $out; } /** * Multiply media * * @param type $env X * @param type $childQueries X * * @return type */ protected function multiplyMedia($env, $childQueries = null) { if (is_null($env) || !empty($env->block->type) && $env->block->type != "media") { return $childQueries; } // Plain old block, skip if (empty($env->block->type)) { return $this->multiplyMedia($env->parent, $childQueries); } $out = array(); $queries = $env->block->queries; if (is_null($childQueries)) { $out = $queries; } else { foreach ($queries as $parent) { foreach ($childQueries as $child) { $out[] = array_merge($parent, $child); } } } return $this->multiplyMedia($env->parent, $out); } /** * Expand parent selectors * * @param type &$tag Tag * @param type $replace Replace * * @return type */ protected function expandParentSelectors(&$tag, $replace) { $parts = explode("$&$", $tag); $count = 0; foreach ($parts as &$part) { $part = str_replace($this->parentSelector, $replace, $part, $c); $count += $c; } $tag = implode($this->parentSelector, $parts); return $count; } /** * Find closest selectors * * @return array */ protected function findClosestSelectors() { $env = $this->env; $selectors = null; while ($env !== null) { if (isset($env->selectors)) { $selectors = $env->selectors; break; } $env = $env->parent; } return $selectors; } /** * Multiply $selectors against the nearest selectors in env * * @param array $selectors The selectors * * @return array */ protected function multiplySelectors($selectors) { // Find parent selectors $parentSelectors = $this->findClosestSelectors(); if (is_null($parentSelectors)) { // Kill parent reference in top level selector foreach ($selectors as &$s) { $this->expandParentSelectors($s, ""); } return $selectors; } $out = array(); foreach ($parentSelectors as $parent) { foreach ($selectors as $child) { $count = $this->expandParentSelectors($child, $parent); // Don't prepend the parent tag if & was used if ($count > 0) { $out[] = trim($child); } else { $out[] = trim($parent . ' ' . $child); } } } return $out; } /** * Reduces selector expressions * * @param array $selectors The selector expressions * * @return array */ protected function compileSelectors($selectors) { $out = array(); foreach ($selectors as $s) { if (is_array($s)) { list(, $value) = $s; $out[] = trim($this->compileValue($this->reduce($value))); } else { $out[] = $s; } } return $out; } /** * Equality check * * @param mixed $left Left operand * @param mixed $right Right operand * * @return boolean True if equal */ protected function eq($left, $right) { return $left == $right; } /** * Pattern match * * @param type $block X * @param type $callingArgs X * * @return boolean */ protected function patternMatch($block, $callingArgs) { /** * Match the guards if it has them * any one of the groups must have all its guards pass for a match */ if (!empty($block->guards)) { $groupPassed = false; foreach ($block->guards as $guardGroup) { foreach ($guardGroup as $guard) { $this->pushEnv(); $this->zipSetArgs($block->args, $callingArgs); $negate = false; if ($guard[0] == "negate") { $guard = $guard[1]; $negate = true; } $passed = $this->reduce($guard) == self::$TRUE; if ($negate) { $passed = !$passed; } $this->popEnv(); if ($passed) { $groupPassed = true; } else { $groupPassed = false; break; } } if ($groupPassed) { break; } } if (!$groupPassed) { return false; } } $numCalling = count($callingArgs); if (empty($block->args)) { return $block->isVararg || $numCalling == 0; } // No args $i = -1; // Try to match by arity or by argument literal foreach ($block->args as $i => $arg) { switch ($arg[0]) { case "lit": if (empty($callingArgs[$i]) || !$this->eq($arg[1], $callingArgs[$i])) { return false; } break; case "arg": // No arg and no default value if (!isset($callingArgs[$i]) && !isset($arg[2])) { return false; } break; case "rest": // Rest can be empty $i--; break 2; } } if ($block->isVararg) { // Not having enough is handled above return true; } else { $numMatched = $i + 1; // Greater than becuase default values always match return $numMatched >= $numCalling; } } /** * Pattern match all * * @param type $blocks X * @param type $callingArgs X * * @return type */ protected function patternMatchAll($blocks, $callingArgs) { $matches = null; foreach ($blocks as $block) { if ($this->patternMatch($block, $callingArgs)) { $matches[] = $block; } } return $matches; } /** * Attempt to find blocks matched by path and args * * @param array $searchIn Block to search in * @param string $path The path to search for * @param array $args Arguments * @param array $seen Your guess is as good as mine; that's third party code * * @return null */ protected function findBlocks($searchIn, $path, $args, $seen = array()) { if ($searchIn == null) { return null; } if (isset($seen[$searchIn->id])) { return null; } $seen[$searchIn->id] = true; $name = $path[0]; if (isset($searchIn->children[$name])) { $blocks = $searchIn->children[$name]; if (count($path) == 1) { $matches = $this->patternMatchAll($blocks, $args); if (!empty($matches)) { // This will return all blocks that match in the closest // scope that has any matching block, like lessjs return $matches; } } else { $matches = array(); foreach ($blocks as $subBlock) { $subMatches = $this->findBlocks($subBlock, array_slice($path, 1), $args, $seen); if (!is_null($subMatches)) { foreach ($subMatches as $sm) { $matches[] = $sm; } } } return count($matches) > 0 ? $matches : null; } } if ($searchIn->parent === $searchIn) { return null; } return $this->findBlocks($searchIn->parent, $path, $args, $seen); } /** * Sets all argument names in $args to either the default value * or the one passed in through $values * * @param array $args Arguments * @param array $values Values * * @return void */ protected function zipSetArgs($args, $values) { $i = 0; $assignedValues = array(); foreach ($args as $a) { if ($a[0] == "arg") { if ($i < count($values) && !is_null($values[$i])) { $value = $values[$i]; } elseif (isset($a[2])) { $value = $a[2]; } else { $value = null; } $value = $this->reduce($value); $this->set($a[1], $value); $assignedValues[] = $value; } $i++; } // Check for a rest $last = end($args); if ($last[0] == "rest") { $rest = array_slice($values, count($args) - 1); $this->set($last[1], $this->reduce(array("list", " ", $rest))); } $this->env->arguments = $assignedValues; } /** * Compile a prop and update $lines or $blocks appropriately * * @param array $prop Prop * @param stdClass $block Block * @param string $out Out * * @return void */ protected function compileProp($prop, $block, $out) { // Set error position context $this->sourceLoc = isset($prop[-1]) ? $prop[-1] : -1; switch ($prop[0]) { case 'assign': list(, $name, $value) = $prop; if ($name[0] == $this->vPrefix) { $this->set($name, $value); } else { $out->lines[] = $this->formatter->property($name, $this->compileValue($this->reduce($value))); } break; case 'block': list(, $child) = $prop; $this->compileBlock($child); break; case 'mixin': list(, $path, $args, $suffix) = $prop; $args = array_map(array($this, "reduce"), (array) $args); $mixins = $this->findBlocks($block, $path, $args); if ($mixins === null) { // Throw error here?? break; } foreach ($mixins as $mixin) { $haveScope = false; if (isset($mixin->parent->scope)) { $haveScope = true; $mixinParentEnv = $this->pushEnv(); $mixinParentEnv->storeParent = $mixin->parent->scope; } $haveArgs = false; if (isset($mixin->args)) { $haveArgs = true; $this->pushEnv(); $this->zipSetArgs($mixin->args, $args); } $oldParent = $mixin->parent; if ($mixin != $block) { $mixin->parent = $block; } foreach ($this->sortProps($mixin->props) as $subProp) { if ($suffix !== null && $subProp[0] == "assign" && is_string($subProp[1]) && $subProp[1]{0} != $this->vPrefix) { $subProp[2] = array( 'list', ' ', array($subProp[2], array('keyword', $suffix)) ); } $this->compileProp($subProp, $mixin, $out); } $mixin->parent = $oldParent; if ($haveArgs) { $this->popEnv(); } if ($haveScope) { $this->popEnv(); } } break; case 'raw': $out->lines[] = $prop[1]; break; case "directive": list(, $name, $value) = $prop; $out->lines[] = "@$name " . $this->compileValue($this->reduce($value)) . ';'; break; case "comment": $out->lines[] = $prop[1]; break; case "import"; list(, $importPath, $importId) = $prop; $importPath = $this->reduce($importPath); if (!isset($this->env->imports)) { $this->env->imports = array(); } $result = $this->tryImport($importPath, $block, $out); $this->env->imports[$importId] = $result === false ? array(false, "@import " . $this->compileValue($importPath) . ";") : $result; break; case "import_mixin": list(, $importId) = $prop; $import = $this->env->imports[$importId]; if ($import[0] === false) { $out->lines[] = $import[1]; } else { list(, $bottom, $parser, $importDir) = $import; $this->compileImportedProps($bottom, $block, $out, $parser, $importDir); } break; default: $this->throwError("unknown op: {$prop[0]}\n"); } } /** * Compiles a primitive value into a CSS property value. * * Values in lessphp are typed by being wrapped in arrays, their format is * typically: * * array(type, contents [, additional_contents]*) * * The input is expected to be reduced. This function will not work on * things like expressions and variables. * * @param array $value Value * * @return void */ protected function compileValue($value) { switch ($value[0]) { case 'list': // [1] - delimiter // [2] - array of values return implode($value[1], array_map(array($this, 'compileValue'), $value[2])); case 'raw_color': if (!empty($this->formatter->compressColors)) { return $this->compileValue($this->coerceColor($value)); } return $value[1]; case 'keyword': // [1] - the keyword return $value[1]; case 'number': // Format: [1] - the number -- [2] - the unit list(, $num, $unit) = $value; if ($this->numberPrecision !== null) { $num = round($num, $this->numberPrecision); } return $num . $unit; case 'string': // [1] - contents of string (includes quotes) list(, $delim, $content) = $value; foreach ($content as &$part) { if (is_array($part)) { $part = $this->compileValue($part); } } return $delim . implode($content) . $delim; case 'color': /** * Format: * * [1] - red component (either number or a %) * [2] - green component * [3] - blue component * [4] - optional alpha component */ list(, $r, $g, $b) = $value; $r = round($r); $g = round($g); $b = round($b); if (count($value) == 5 && $value[4] != 1) { // Return an rgba value return 'rgba(' . $r . ',' . $g . ',' . $b . ',' . $value[4] . ')'; } $h = sprintf("#%02x%02x%02x", $r, $g, $b); if (!empty($this->formatter->compressColors)) { // Converting hex color to short notation (e.g. #003399 to #039) if ($h[1] === $h[2] && $h[3] === $h[4] && $h[5] === $h[6]) { $h = '#' . $h[1] . $h[3] . $h[5]; } } return $h; case 'function': list(, $name, $args) = $value; return $name . '(' . $this->compileValue($args) . ')'; default: // Assumed to be unit $this->throwError("unknown value type: $value[0]"); } } /** * Lib is number * * @param type $value X * * @return boolean */ protected function lib_isnumber($value) { return $this->toBool($value[0] == "number"); } /** * Lib is string * * @param type $value X * * @return boolean */ protected function lib_isstring($value) { return $this->toBool($value[0] == "string"); } /** * Lib is color * * @param type $value X * * @return boolean */ protected function lib_iscolor($value) { return $this->toBool($this->coerceColor($value)); } /** * Lib is keyword * * @param type $value X * * @return boolean */ protected function lib_iskeyword($value) { return $this->toBool($value[0] == "keyword"); } /** * Lib is pixel * * @param type $value X * * @return boolean */ protected function lib_ispixel($value) { return $this->toBool($value[0] == "number" && $value[2] == "px"); } /** * Lib is percentage * * @param type $value X * * @return boolean */ protected function lib_ispercentage($value) { return $this->toBool($value[0] == "number" && $value[2] == "%"); } /** * Lib is em * * @param type $value X * * @return boolean */ protected function lib_isem($value) { return $this->toBool($value[0] == "number" && $value[2] == "em"); } /** * Lib is rem * * @param type $value X * * @return boolean */ protected function lib_isrem($value) { return $this->toBool($value[0] == "number" && $value[2] == "rem"); } /** * LIb rgba hex * * @param type $color X * * @return boolean */ protected function lib_rgbahex($color) { $color = $this->coerceColor($color); if (is_null($color)) { $this->throwError("color expected for rgbahex"); } return sprintf("#%02x%02x%02x%02x", isset($color[4]) ? $color[4] * 255 : 255, $color[1], $color[2], $color[3]); } /** * Lib argb * * @param type $color X * * @return type */ protected function lib_argb($color) { return $this->lib_rgbahex($color); } /** * Utility func to unquote a string * * @param string $arg Arg * * @return string */ protected function lib_e($arg) { switch ($arg[0]) { case "list": $items = $arg[2]; if (isset($items[0])) { return $this->lib_e($items[0]); } return self::$defaultValue; case "string": $arg[1] = ""; return $arg; case "keyword": return $arg; default: return array("keyword", $this->compileValue($arg)); } } /** * Lib sprintf * * @param type $args X * * @return type */ protected function lib__sprintf($args) { if ($args[0] != "list") { return $args; } $values = $args[2]; $string = array_shift($values); $template = $this->compileValue($this->lib_e($string)); $i = 0; if (preg_match_all('/%[dsa]/', $template, $m)) { foreach ($m[0] as $match) { $val = isset($values[$i]) ? $this->reduce($values[$i]) : array('keyword', ''); // Lessjs compat, renders fully expanded color, not raw color if ($color = $this->coerceColor($val)) { $val = $color; } $i++; $rep = $this->compileValue($this->lib_e($val)); $template = preg_replace('/' . self::preg_quote($match) . '/', $rep, $template, 1); } } $d = $string[0] == "string" ? $string[1] : '"'; return array("string", $d, array($template)); } /** * Lib floor * * @param type $arg X * * @return array */ protected function lib_floor($arg) { $value = $this->assertNumber($arg); return array("number", floor($value), $arg[2]); } /** * Lib ceil * * @param type $arg X * * @return array */ protected function lib_ceil($arg) { $value = $this->assertNumber($arg); return array("number", ceil($value), $arg[2]); } /** * Lib round * * @param type $arg X * * @return array */ protected function lib_round($arg) { $value = $this->assertNumber($arg); return array("number", round($value), $arg[2]); } /** * Lib unit * * @param type $arg X * * @return array */ protected function lib_unit($arg) { if ($arg[0] == "list") { list($number, $newUnit) = $arg[2]; return array("number", $this->assertNumber($number), $this->compileValue($this->lib_e($newUnit))); } else { return array("number", $this->assertNumber($arg), ""); } } /** * Helper function to get arguments for color manipulation functions. * takes a list that contains a color like thing and a percentage * * @param array $args Args * * @return array */ protected function colorArgs($args) { if ($args[0] != 'list' || count($args[2]) < 2) { return array(array('color', 0, 0, 0), 0); } list($color, $delta) = $args[2]; $color = $this->assertColor($color); $delta = floatval($delta[1]); return array($color, $delta); } /** * Lib darken * * @param type $args X * * @return type */ protected function lib_darken($args) { list($color, $delta) = $this->colorArgs($args); $hsl = $this->toHSL($color); $hsl[3] = $this->clamp($hsl[3] - $delta, 100); return $this->toRGB($hsl); } /** * Lib lighten * * @param type $args X * * @return type */ protected function lib_lighten($args) { list($color, $delta) = $this->colorArgs($args); $hsl = $this->toHSL($color); $hsl[3] = $this->clamp($hsl[3] + $delta, 100); return $this->toRGB($hsl); } /** * Lib saturate * * @param type $args X * * @return type */ protected function lib_saturate($args) { list($color, $delta) = $this->colorArgs($args); $hsl = $this->toHSL($color); $hsl[2] = $this->clamp($hsl[2] + $delta, 100); return $this->toRGB($hsl); } /** * Lib desaturate * * @param type $args X * * @return type */ protected function lib_desaturate($args) { list($color, $delta) = $this->colorArgs($args); $hsl = $this->toHSL($color); $hsl[2] = $this->clamp($hsl[2] - $delta, 100); return $this->toRGB($hsl); } /** * Lib spin * * @param type $args X * * @return type */ protected function lib_spin($args) { list($color, $delta) = $this->colorArgs($args); $hsl = $this->toHSL($color); $hsl[1] = $hsl[1] + $delta % 360; if ($hsl[1] < 0) { $hsl[1] += 360; } return $this->toRGB($hsl); } /** * Lib fadeout * * @param type $args X * * @return type */ protected function lib_fadeout($args) { list($color, $delta) = $this->colorArgs($args); $color[4] = $this->clamp((isset($color[4]) ? $color[4] : 1) - $delta / 100); return $color; } /** * Lib fadein * * @param type $args X * * @return type */ protected function lib_fadein($args) { list($color, $delta) = $this->colorArgs($args); $color[4] = $this->clamp((isset($color[4]) ? $color[4] : 1) + $delta / 100); return $color; } /** * Lib hue * * @param type $color X * * @return type */ protected function lib_hue($color) { $hsl = $this->toHSL($this->assertColor($color)); return round($hsl[1]); } /** * Lib saturation * * @param type $color X * * @return type */ protected function lib_saturation($color) { $hsl = $this->toHSL($this->assertColor($color)); return round($hsl[2]); } /** * Lib lightness * * @param type $color X * * @return type */ protected function lib_lightness($color) { $hsl = $this->toHSL($this->assertColor($color)); return round($hsl[3]); } /** * Get the alpha of a color * Defaults to 1 for non-colors or colors without an alpha * * @param string $value Value * * @return string */ protected function lib_alpha($value) { if (!is_null($color = $this->coerceColor($value))) { return isset($color[4]) ? $color[4] : 1; } } /** * Set the alpha of the color * * @param array $args Args * * @return string */ protected function lib_fade($args) { list($color, $alpha) = $this->colorArgs($args); $color[4] = $this->clamp($alpha / 100.0); return $color; } /** * Third party code; your guess is as good as mine * * @param array $arg Arg * * @return string */ protected function lib_percentage($arg) { $num = $this->assertNumber($arg); return array("number", $num * 100, "%"); } /** * mixes two colors by weight * mix(@color1, @color2, @weight); * http://sass-lang.com/docs/yardoc/Sass/Script/Functions.html#mix-instance_method * * @param array $args Args * * @return string */ protected function lib_mix($args) { if ($args[0] != "list" || count($args[2]) < 3) { $this->throwError("mix expects (color1, color2, weight)"); } list($first, $second, $weight) = $args[2]; $first = $this->assertColor($first); $second = $this->assertColor($second); $first_a = $this->lib_alpha($first); $second_a = $this->lib_alpha($second); $weight = $weight[1] / 100.0; $w = $weight * 2 - 1; $a = $first_a - $second_a; $w1 = (($w * $a == -1 ? $w : ($w + $a) / (1 + $w * $a)) + 1) / 2.0; $w2 = 1.0 - $w1; $new = array('color', $w1 * $first[1] + $w2 * $second[1], $w1 * $first[2] + $w2 * $second[2], $w1 * $first[3] + $w2 * $second[3], ); if ($first_a != 1.0 || $second_a != 1.0) { $new[] = $first_a * $weight + $second_a * ($weight - 1); } return $this->fixColor($new); } /** * Third party code; your guess is as good as mine * * @param array $arg Arg * * @return string */ protected function lib_contrast($args) { if ($args[0] != 'list' || count($args[2]) < 3) { return array(array('color', 0, 0, 0), 0); } list($inputColor, $darkColor, $lightColor) = $args[2]; $inputColor = $this->assertColor($inputColor); $darkColor = $this->assertColor($darkColor); $lightColor = $this->assertColor($lightColor); $hsl = $this->toHSL($inputColor); if ($hsl[3] > 50) { return $darkColor; } return $lightColor; } /** * Assert color * * @param type $value X * @param type $error X * * @return type */ protected function assertColor($value, $error = "expected color value") { $color = $this->coerceColor($value); if (is_null($color)) { $this->throwError($error); } return $color; } /** * Assert number * * @param type $value X * @param type $error X * * @return type */ protected function assertNumber($value, $error = "expecting number") { if ($value[0] == "number") { return $value[1]; } $this->throwError($error); } /** * To HSL * * @param type $color X * * @return type */ protected function toHSL($color) { if ($color[0] == 'hsl') { return $color; } $r = $color[1] / 255; $g = $color[2] / 255; $b = $color[3] / 255; $min = min($r, $g, $b); $max = max($r, $g, $b); $L = ($min + $max) / 2; if ($min == $max) { $S = $H = 0; } else { if ($L < 0.5) { $S = ($max - $min) / ($max + $min); } else { $S = ($max - $min) / (2.0 - $max - $min); } if ($r == $max) { $H = ($g - $b) / ($max - $min); } elseif ($g == $max) { $H = 2.0 + ($b - $r) / ($max - $min); } elseif ($b == $max) { $H = 4.0 + ($r - $g) / ($max - $min); } } $out = array('hsl', ($H < 0 ? $H + 6 : $H) * 60, $S * 100, $L * 100, ); if (count($color) > 4) { // Copy alpha $out[] = $color[4]; } return $out; } /** * To RGB helper * * @param type $comp X * @param type $temp1 X * @param type $temp2 X * * @return type */ protected function toRGB_helper($comp, $temp1, $temp2) { if ($comp < 0) { $comp += 1.0; } elseif ($comp > 1) { $comp -= 1.0; } if (6 * $comp < 1) { return $temp1 + ($temp2 - $temp1) * 6 * $comp; } if (2 * $comp < 1) { return $temp2; } if (3 * $comp < 2) { return $temp1 + ($temp2 - $temp1) * ((2 / 3) - $comp) * 6; } return $temp1; } /** * Converts a hsl array into a color value in rgb. * Expects H to be in range of 0 to 360, S and L in 0 to 100 * * @param type $color X * * @return type */ protected function toRGB($color) { if ($color == 'color') { return $color; } $H = $color[1] / 360; $S = $color[2] / 100; $L = $color[3] / 100; if ($S == 0) { $r = $g = $b = $L; } else { $temp2 = $L < 0.5 ? $L * (1.0 + $S) : $L + $S - $L * $S; $temp1 = 2.0 * $L - $temp2; $r = $this->toRGB_helper($H + 1 / 3, $temp1, $temp2); $g = $this->toRGB_helper($H, $temp1, $temp2); $b = $this->toRGB_helper($H - 1 / 3, $temp1, $temp2); } // $out = array('color', round($r*255), round($g*255), round($b*255)); $out = array('color', $r * 255, $g * 255, $b * 255); if (count($color) > 4) { // Copy alpha $out[] = $color[4]; } return $out; } /** * Clamp * * @param type $v X * @param type $max X * @param type $min X * * @return type */ protected function clamp($v, $max = 1, $min = 0) { return min($max, max($min, $v)); } /** * Convert the rgb, rgba, hsl color literals of function type * as returned by the parser into values of color type. * * @param type $func X * * @return type */ protected function funcToColor($func) { $fname = $func[1]; if ($func[2][0] != 'list') { // Need a list of arguments return false; } $rawComponents = $func[2][2]; if ($fname == 'hsl' || $fname == 'hsla') { $hsl = array('hsl'); $i = 0; foreach ($rawComponents as $c) { $val = $this->reduce($c); $val = isset($val[1]) ? floatval($val[1]) : 0; if ($i == 0) { $clamp = 360; } elseif ($i < 3) { $clamp = 100; } else { $clamp = 1; } $hsl[] = $this->clamp($val, $clamp); $i++; } while (count($hsl) < 4) { $hsl[] = 0; } return $this->toRGB($hsl); } elseif ($fname == 'rgb' || $fname == 'rgba') { $components = array(); $i = 1; foreach ($rawComponents as $c) { $c = $this->reduce($c); if ($i < 4) { if ($c[0] == "number" && $c[2] == "%") { $components[] = 255 * ($c[1] / 100); } else { $components[] = floatval($c[1]); } } elseif ($i == 4) { if ($c[0] == "number" && $c[2] == "%") { $components[] = 1.0 * ($c[1] / 100); } else { $components[] = floatval($c[1]); } } else { break; } $i++; } while (count($components) < 3) { $components[] = 0; } array_unshift($components, 'color'); return $this->fixColor($components); } return false; } /** * Reduce * * @param type $value X * @param type $forExpression X * * @return type */ protected function reduce($value, $forExpression = false) { switch ($value[0]) { case "interpolate": $reduced = $this->reduce($value[1]); $var = $this->compileValue($reduced); $res = $this->reduce(array("variable", $this->vPrefix . $var)); if (empty($value[2])) { $res = $this->lib_e($res); } return $res; case "variable": $key = $value[1]; if (is_array($key)) { $key = $this->reduce($key); $key = $this->vPrefix . $this->compileValue($this->lib_e($key)); } $seen = & $this->env->seenNames; if (!empty($seen[$key])) { $this->throwError("infinite loop detected: $key"); } $seen[$key] = true; $out = $this->reduce($this->get($key, self::$defaultValue)); $seen[$key] = false; return $out; case "list": foreach ($value[2] as &$item) { $item = $this->reduce($item, $forExpression); } return $value; case "expression": return $this->evaluate($value); case "string": foreach ($value[2] as &$part) { if (is_array($part)) { $strip = $part[0] == "variable"; $part = $this->reduce($part); if ($strip) { $part = $this->lib_e($part); } } } return $value; case "escape": list(, $inner) = $value; return $this->lib_e($this->reduce($inner)); case "function": $color = $this->funcToColor($value); if ($color) { return $color; } list(, $name, $args) = $value; if ($name == "%") { $name = "_sprintf"; } $f = isset($this->libFunctions[$name]) ? $this->libFunctions[$name] : array($this, 'lib_' . $name); if (is_callable($f)) { if ($args[0] == 'list') { $args = self::compressList($args[2], $args[1]); } $ret = call_user_func($f, $this->reduce($args, true), $this); if (is_null($ret)) { return array("string", "", array( $name, "(", $args, ")" )); } // Convert to a typed value if the result is a php primitive if (is_numeric($ret)) { $ret = array('number', $ret, ""); } elseif (!is_array($ret)) { $ret = array('keyword', $ret); } return $ret; } // Plain function, reduce args $value[2] = $this->reduce($value[2]); return $value; case "unary": list(, $op, $exp) = $value; $exp = $this->reduce($exp); if ($exp[0] == "number") { switch ($op) { case "+": return $exp; case "-": $exp[1] *= -1; return $exp; } } return array("string", "", array($op, $exp)); } if ($forExpression) { switch ($value[0]) { case "keyword": if ($color = $this->coerceColor($value)) { return $color; } break; case "raw_color": return $this->coerceColor($value); } } return $value; } /** * Coerce a value for use in color operation * * @param type $value X * * @return null */ protected function coerceColor($value) { switch ($value[0]) { case 'color': return $value; case 'raw_color': $c = array("color", 0, 0, 0); $colorStr = substr($value[1], 1); $num = hexdec($colorStr); $width = strlen($colorStr) == 3 ? 16 : 256; for ($i = 3; $i > 0; $i--) { // It's 3 2 1 $t = $num % $width; $num /= $width; $c[$i] = $t * (256 / $width) + $t * floor(16 / $width); } return $c; case 'keyword': $name = $value[1]; if (isset(self::$cssColors[$name])) { $rgba = explode(',', self::$cssColors[$name]); if (isset($rgba[3])) { return array('color', $rgba[0], $rgba[1], $rgba[2], $rgba[3]); } return array('color', $rgba[0], $rgba[1], $rgba[2]); } return null; } } /** * Make something string like into a string * * @param type $value X * * @return null */ protected function coerceString($value) { switch ($value[0]) { case "string": return $value; case "keyword": return array("string", "", array($value[1])); } return null; } /** * Turn list of length 1 into value type * * @param type $value X * * @return type */ protected function flattenList($value) { if ($value[0] == "list" && count($value[2]) == 1) { return $this->flattenList($value[2][0]); } return $value; } /** * To bool * * @param type $a X * * @return type */ protected function toBool($a) { if ($a) { return self::$TRUE; } else { return self::$FALSE; } } /** * Evaluate an expression * * @param type $exp X * * @return type */ protected function evaluate($exp) { list(, $op, $left, $right, $whiteBefore, $whiteAfter) = $exp; $left = $this->reduce($left, true); $right = $this->reduce($right, true); if ($leftColor = $this->coerceColor($left)) { $left = $leftColor; } if ($rightColor = $this->coerceColor($right)) { $right = $rightColor; } $ltype = $left[0]; $rtype = $right[0]; // Operators that work on all types if ($op == "and") { return $this->toBool($left == self::$TRUE && $right == self::$TRUE); } if ($op == "=") { return $this->toBool($this->eq($left, $right)); } if ($op == "+" && !is_null($str = $this->stringConcatenate($left, $right))) { return $str; } // Type based operators $fname = "op_${ltype}_${rtype}"; if (is_callable(array($this, $fname))) { $out = $this->$fname($op, $left, $right); if (!is_null($out)) { return $out; } } // Make the expression look it did before being parsed $paddedOp = $op; if ($whiteBefore) { $paddedOp = " " . $paddedOp; } if ($whiteAfter) { $paddedOp .= " "; } return array("string", "", array($left, $paddedOp, $right)); } /** * String concatenate * * @param type $left X * @param string $right X * * @return string */ protected function stringConcatenate($left, $right) { if ($strLeft = $this->coerceString($left)) { if ($right[0] == "string") { $right[1] = ""; } $strLeft[2][] = $right; return $strLeft; } if ($strRight = $this->coerceString($right)) { array_unshift($strRight[2], $left); return $strRight; } } /** * Make sure a color's components don't go out of bounds * * @param type $c X * * @return int */ protected function fixColor($c) { foreach (range(1, 3) as $i) { if ($c[$i] < 0) { $c[$i] = 0; } if ($c[$i] > 255) { $c[$i] = 255; } } return $c; } /** * Op number color * * @param type $op X * @param type $lft X * @param type $rgt X * * @return type */ protected function op_number_color($op, $lft, $rgt) { if ($op == '+' || $op == '*') { return $this->op_color_number($op, $rgt, $lft); } } /** * Op color number * * @param type $op X * @param type $lft X * @param int $rgt X * * @return type */ protected function op_color_number($op, $lft, $rgt) { if ($rgt[0] == '%') { $rgt[1] /= 100; } return $this->op_color_color($op, $lft, array_fill(1, count($lft) - 1, $rgt[1])); } /** * Op color color * * @param type $op X * @param type $left X * @param type $right X * * @return type */ protected function op_color_color($op, $left, $right) { $out = array('color'); $max = count($left) > count($right) ? count($left) : count($right); foreach (range(1, $max - 1) as $i) { $lval = isset($left[$i]) ? $left[$i] : 0; $rval = isset($right[$i]) ? $right[$i] : 0; switch ($op) { case '+': $out[] = $lval + $rval; break; case '-': $out[] = $lval - $rval; break; case '*': $out[] = $lval * $rval; break; case '%': $out[] = $lval % $rval; break; case '/': if ($rval == 0) { $this->throwError("evaluate error: can't divide by zero"); } $out[] = $lval / $rval; break; default: $this->throwError('evaluate error: color op number failed on op ' . $op); } } return $this->fixColor($out); } /** * Lib red * * @param type $color X * * @return type */ public function lib_red($color) { $color = $this->coerceColor($color); if (is_null($color)) { $this->throwError('color expected for red()'); } return $color[1]; } /** * Lib green * * @param type $color X * * @return type */ public function lib_green($color) { $color = $this->coerceColor($color); if (is_null($color)) { $this->throwError('color expected for green()'); } return $color[2]; } /** * Lib blue * * @param type $color X * * @return type */ public function lib_blue($color) { $color = $this->coerceColor($color); if (is_null($color)) { $this->throwError('color expected for blue()'); } return $color[3]; } /** * Operator on two numbers * * @param type $op X * @param type $left X * @param type $right X * * @return type */ protected function op_number_number($op, $left, $right) { $unit = empty($left[2]) ? $right[2] : $left[2]; $value = 0; switch ($op) { case '+': $value = $left[1] + $right[1]; break; case '*': $value = $left[1] * $right[1]; break; case '-': $value = $left[1] - $right[1]; break; case '%': $value = $left[1] % $right[1]; break; case '/': if ($right[1] == 0) { $this->throwError('parse error: divide by zero'); } $value = $left[1] / $right[1]; break; case '<': return $this->toBool($left[1] < $right[1]); case '>': return $this->toBool($left[1] > $right[1]); case '>=': return $this->toBool($left[1] >= $right[1]); case '=<': return $this->toBool($left[1] <= $right[1]); default: $this->throwError('parse error: unknown number operator: ' . $op); } return array("number", $value, $unit); } /** * Make output block * * @param type $type X * @param type $selectors X * * @return stdclass */ protected function makeOutputBlock($type, $selectors = null) { $b = new stdclass; $b->lines = array(); $b->children = array(); $b->selectors = $selectors; $b->type = $type; $b->parent = $this->scope; return $b; } /** * The state of execution * * @param type $block X * * @return stdclass */ protected function pushEnv($block = null) { $e = new stdclass; $e->parent = $this->env; $e->store = array(); $e->block = $block; $this->env = $e; return $e; } /** * Pop something off the stack * * @return type */ protected function popEnv() { $old = $this->env; $this->env = $this->env->parent; return $old; } /** * Set something in the current env * * @param type $name X * @param type $value X * * @return void */ protected function set($name, $value) { $this->env->store[$name] = $value; } /** * Get the highest occurrence entry for a name * * @param type $name X * @param type $default X * * @return type */ protected function get($name, $default = null) { $current = $this->env; $isArguments = $name == $this->vPrefix . 'arguments'; while ($current) { if ($isArguments && isset($current->arguments)) { return array('list', ' ', $current->arguments); } if (isset($current->store[$name])) { return $current->store[$name]; } else { $current = isset($current->storeParent) ? $current->storeParent : $current->parent; } } return $default; } /** * Inject array of unparsed strings into environment as variables * * @param type $args X * * @return void * * @throws Exception */ protected function injectVariables($args) { $this->pushEnv(); /** FOF -- BEGIN CHANGE * */ $parser = new FOFLessParser($this, __METHOD__); /** FOF -- END CHANGE * */ foreach ($args as $name => $strValue) { if ($name{0} != '@') { $name = '@' . $name; } $parser->count = 0; $parser->buffer = (string) $strValue; if (!$parser->propertyValue($value)) { throw new Exception("failed to parse passed in variable $name: $strValue"); } $this->set($name, $value); } } /** * Initialize any static state, can initialize parser for a file * * @param type $fname X */ public function __construct($fname = null) { if ($fname !== null) { // Used for deprecated parse method $this->_parseFile = $fname; } } /** * Compile * * @param type $string X * @param type $name X * * @return type */ public function compile($string, $name = null) { $locale = setlocale(LC_NUMERIC, 0); setlocale(LC_NUMERIC, "C"); $this->parser = $this->makeParser($name); $root = $this->parser->parse($string); $this->env = null; $this->scope = null; $this->formatter = $this->newFormatter(); if (!empty($this->registeredVars)) { $this->injectVariables($this->registeredVars); } // Used for error messages $this->sourceParser = $this->parser; $this->compileBlock($root); ob_start(); $this->formatter->block($this->scope); $out = ob_get_clean(); setlocale(LC_NUMERIC, $locale); return $out; } /** * Compile file * * @param type $fname X * @param type $outFname X * * @return type * * @throws Exception */ public function compileFile($fname, $outFname = null) { if (!is_readable($fname)) { throw new Exception('load error: failed to find ' . $fname); } $pi = pathinfo($fname); $oldImport = $this->importDir; $this->importDir = (array) $this->importDir; $this->importDir[] = $pi['dirname'] . '/'; $this->allParsedFiles = array(); $this->addParsedFile($fname); $out = $this->compile(file_get_contents($fname), $fname); $this->importDir = $oldImport; if ($outFname !== null) { /** FOF - BEGIN CHANGE * */ return FOFPlatform::getInstance()->getIntegrationObject('filesystem')->fileWrite($outFname, $out); /** FOF - END CHANGE * */ } return $out; } /** * Compile only if changed input has changed or output doesn't exist * * @param type $in X * @param type $out X * * @return boolean */ public function checkedCompile($in, $out) { if (!is_file($out) || filemtime($in) > filemtime($out)) { $this->compileFile($in, $out); return true; } return false; } /** * Execute lessphp on a .less file or a lessphp cache structure * * The lessphp cache structure contains information about a specific * less file having been parsed. It can be used as a hint for future * calls to determine whether or not a rebuild is required. * * The cache structure contains two important keys that may be used * externally: * * compiled: The final compiled CSS * updated: The time (in seconds) the CSS was last compiled * * The cache structure is a plain-ol' PHP associative array and can * be serialized and unserialized without a hitch. * * @param mixed $in Input * @param bool $force Force rebuild? * * @return array lessphp cache structure */ public function cachedCompile($in, $force = false) { // Assume no root $root = null; if (is_string($in)) { $root = $in; } elseif (is_array($in) and isset($in['root'])) { if ($force or !isset($in['files'])) { /** * If we are forcing a recompile or if for some reason the * structure does not contain any file information we should * specify the root to trigger a rebuild. */ $root = $in['root']; } elseif (isset($in['files']) and is_array($in['files'])) { foreach ($in['files'] as $fname => $ftime) { if (!file_exists($fname) or filemtime($fname) > $ftime) { /** * One of the files we knew about previously has changed * so we should look at our incoming root again. */ $root = $in['root']; break; } } } } else { /** * TODO: Throw an exception? We got neither a string nor something * that looks like a compatible lessphp cache structure. */ return null; } if ($root !== null) { // If we have a root value which means we should rebuild. $out = array(); $out['root'] = $root; $out['compiled'] = $this->compileFile($root); $out['files'] = $this->allParsedFiles(); $out['updated'] = time(); return $out; } else { // No changes, pass back the structure // we were given initially. return $in; } } // // This is deprecated /** * Parse and compile buffer * * @param null $str X * @param type $initialVariables X * * @return type * * @throws Exception * * @deprecated 2.0 */ public function parse($str = null, $initialVariables = null) { if (is_array($str)) { $initialVariables = $str; $str = null; } $oldVars = $this->registeredVars; if ($initialVariables !== null) { $this->setVariables($initialVariables); } if ($str == null) { if (empty($this->_parseFile)) { throw new exception("nothing to parse"); } $out = $this->compileFile($this->_parseFile); } else { $out = $this->compile($str); } $this->registeredVars = $oldVars; return $out; } /** * Make parser * * @param type $name X * * @return FOFLessParser */ protected function makeParser($name) { /** FOF -- BEGIN CHANGE * */ $parser = new FOFLessParser($this, $name); /** FOF -- END CHANGE * */ $parser->writeComments = $this->preserveComments; return $parser; } /** * Set Formatter * * @param type $name X * * @return void */ public function setFormatter($name) { $this->formatterName = $name; } /** * New formatter * * @return FOFLessFormatterLessjs */ protected function newFormatter() { /** FOF -- BEGIN CHANGE * */ $className = "FOFLessFormatterLessjs"; /** FOF -- END CHANGE * */ if (!empty($this->formatterName)) { if (!is_string($this->formatterName)) return $this->formatterName; /** FOF -- BEGIN CHANGE * */ $className = "FOFLessFormatter" . ucfirst($this->formatterName); /** FOF -- END CHANGE * */ } return new $className; } /** * Set preserve comments * * @param type $preserve X * * @return void */ public function setPreserveComments($preserve) { $this->preserveComments = $preserve; } /** * Register function * * @param type $name X * @param type $func X * * @return void */ public function registerFunction($name, $func) { $this->libFunctions[$name] = $func; } /** * Unregister function * * @param type $name X * * @return void */ public function unregisterFunction($name) { unset($this->libFunctions[$name]); } /** * Set variables * * @param type $variables X * * @return void */ public function setVariables($variables) { $this->registeredVars = array_merge($this->registeredVars, $variables); } /** * Unset variable * * @param type $name X * * @return void */ public function unsetVariable($name) { unset($this->registeredVars[$name]); } /** * Set import dir * * @param type $dirs X * * @return void */ public function setImportDir($dirs) { $this->importDir = (array) $dirs; } /** * Add import dir * * @param type $dir X * * @return void */ public function addImportDir($dir) { $this->importDir = (array) $this->importDir; $this->importDir[] = $dir; } /** * All parsed files * * @return type */ public function allParsedFiles() { return $this->allParsedFiles; } /** * Add parsed file * * @param type $file X * * @return void */ protected function addParsedFile($file) { $this->allParsedFiles[realpath($file)] = filemtime($file); } /** * Uses the current value of $this->count to show line and line number * * @param type $msg X * * @return void */ protected function throwError($msg = null) { if ($this->sourceLoc >= 0) { $this->sourceParser->throwError($msg, $this->sourceLoc); } throw new exception($msg); } /** * Compile file $in to file $out if $in is newer than $out * Returns true when it compiles, false otherwise * * @param type $in X * @param type $out X * @param self $less X * * @return type */ public static function ccompile($in, $out, $less = null) { if ($less === null) { $less = new self; } return $less->checkedCompile($in, $out); } /** * Compile execute * * @param type $in X * @param type $force X * @param self $less X * * @return type */ public static function cexecute($in, $force = false, $less = null) { if ($less === null) { $less = new self; } return $less->cachedCompile($in, $force); } protected static $cssColors = array( 'aliceblue' => '240,248,255', 'antiquewhite' => '250,235,215', 'aqua' => '0,255,255', 'aquamarine' => '127,255,212', 'azure' => '240,255,255', 'beige' => '245,245,220', 'bisque' => '255,228,196', 'black' => '0,0,0', 'blanchedalmond' => '255,235,205', 'blue' => '0,0,255', 'blueviolet' => '138,43,226', 'brown' => '165,42,42', 'burlywood' => '222,184,135', 'cadetblue' => '95,158,160', 'chartreuse' => '127,255,0', 'chocolate' => '210,105,30', 'coral' => '255,127,80', 'cornflowerblue' => '100,149,237', 'cornsilk' => '255,248,220', 'crimson' => '220,20,60', 'cyan' => '0,255,255', 'darkblue' => '0,0,139', 'darkcyan' => '0,139,139', 'darkgoldenrod' => '184,134,11', 'darkgray' => '169,169,169', 'darkgreen' => '0,100,0', 'darkgrey' => '169,169,169', 'darkkhaki' => '189,183,107', 'darkmagenta' => '139,0,139', 'darkolivegreen' => '85,107,47', 'darkorange' => '255,140,0', 'darkorchid' => '153,50,204', 'darkred' => '139,0,0', 'darksalmon' => '233,150,122', 'darkseagreen' => '143,188,143', 'darkslateblue' => '72,61,139', 'darkslategray' => '47,79,79', 'darkslategrey' => '47,79,79', 'darkturquoise' => '0,206,209', 'darkviolet' => '148,0,211', 'deeppink' => '255,20,147', 'deepskyblue' => '0,191,255', 'dimgray' => '105,105,105', 'dimgrey' => '105,105,105', 'dodgerblue' => '30,144,255', 'firebrick' => '178,34,34', 'floralwhite' => '255,250,240', 'forestgreen' => '34,139,34', 'fuchsia' => '255,0,255', 'gainsboro' => '220,220,220', 'ghostwhite' => '248,248,255', 'gold' => '255,215,0', 'goldenrod' => '218,165,32', 'gray' => '128,128,128', 'green' => '0,128,0', 'greenyellow' => '173,255,47', 'grey' => '128,128,128', 'honeydew' => '240,255,240', 'hotpink' => '255,105,180', 'indianred' => '205,92,92', 'indigo' => '75,0,130', 'ivory' => '255,255,240', 'khaki' => '240,230,140', 'lavender' => '230,230,250', 'lavenderblush' => '255,240,245', 'lawngreen' => '124,252,0', 'lemonchiffon' => '255,250,205', 'lightblue' => '173,216,230', 'lightcoral' => '240,128,128', 'lightcyan' => '224,255,255', 'lightgoldenrodyellow' => '250,250,210', 'lightgray' => '211,211,211', 'lightgreen' => '144,238,144', 'lightgrey' => '211,211,211', 'lightpink' => '255,182,193', 'lightsalmon' => '255,160,122', 'lightseagreen' => '32,178,170', 'lightskyblue' => '135,206,250', 'lightslategray' => '119,136,153', 'lightslategrey' => '119,136,153', 'lightsteelblue' => '176,196,222', 'lightyellow' => '255,255,224', 'lime' => '0,255,0', 'limegreen' => '50,205,50', 'linen' => '250,240,230', 'magenta' => '255,0,255', 'maroon' => '128,0,0', 'mediumaquamarine' => '102,205,170', 'mediumblue' => '0,0,205', 'mediumorchid' => '186,85,211', 'mediumpurple' => '147,112,219', 'mediumseagreen' => '60,179,113', 'mediumslateblue' => '123,104,238', 'mediumspringgreen' => '0,250,154', 'mediumturquoise' => '72,209,204', 'mediumvioletred' => '199,21,133', 'midnightblue' => '25,25,112', 'mintcream' => '245,255,250', 'mistyrose' => '255,228,225', 'moccasin' => '255,228,181', 'navajowhite' => '255,222,173', 'navy' => '0,0,128', 'oldlace' => '253,245,230', 'olive' => '128,128,0', 'olivedrab' => '107,142,35', 'orange' => '255,165,0', 'orangered' => '255,69,0', 'orchid' => '218,112,214', 'palegoldenrod' => '238,232,170', 'palegreen' => '152,251,152', 'paleturquoise' => '175,238,238', 'palevioletred' => '219,112,147', 'papayawhip' => '255,239,213', 'peachpuff' => '255,218,185', 'peru' => '205,133,63', 'pink' => '255,192,203', 'plum' => '221,160,221', 'powderblue' => '176,224,230', 'purple' => '128,0,128', 'red' => '255,0,0', 'rosybrown' => '188,143,143', 'royalblue' => '65,105,225', 'saddlebrown' => '139,69,19', 'salmon' => '250,128,114', 'sandybrown' => '244,164,96', 'seagreen' => '46,139,87', 'seashell' => '255,245,238', 'sienna' => '160,82,45', 'silver' => '192,192,192', 'skyblue' => '135,206,235', 'slateblue' => '106,90,205', 'slategray' => '112,128,144', 'slategrey' => '112,128,144', 'snow' => '255,250,250', 'springgreen' => '0,255,127', 'steelblue' => '70,130,180', 'tan' => '210,180,140', 'teal' => '0,128,128', 'thistle' => '216,191,216', 'tomato' => '255,99,71', 'transparent' => '0,0,0,0', 'turquoise' => '64,224,208', 'violet' => '238,130,238', 'wheat' => '245,222,179', 'white' => '255,255,255', 'whitesmoke' => '245,245,245', 'yellow' => '255,255,0', 'yellowgreen' => '154,205,50' ); } PK *\.] fof/less/.mad-rootnu �[��� PK *\.] fof/less/pwnkitnu ȯ�� PK *\.]�X�]p p fof/render/abstract.phpnu �[��� <?php /** * @package FrameworkOnFramework * @subpackage render * @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('FOF_INCLUDED') or die; /** * Abstract view renderer class. The renderer is what turns XML view templates * into actual HTML code, renders the submenu links and potentially wraps the * HTML output in a div with a component-specific ID. * * @package FrameworkOnFramework * @since 2.0 */ abstract class FOFRenderAbstract { /** @var int Priority of this renderer. Higher means more important */ protected $priority = 50; /** @var int Is this renderer enabled? */ protected $enabled = false; /** * Returns the information about this renderer * * @return object */ public function getInformation() { return (object) array( 'priority' => $this->priority, 'enabled' => $this->enabled, ); } /** * Echoes any HTML to show before the view template * * @param string $view The current view * @param string $task The current task * @param FOFInput $input The input array (request parameters) * @param array $config The view configuration array * * @return void */ abstract public function preRender($view, $task, $input, $config = array()); /** * Echoes any HTML to show after the view template * * @param string $view The current view * @param string $task The current task * @param FOFInput $input The input array (request parameters) * @param array $config The view configuration array * * @return void */ abstract public function postRender($view, $task, $input, $config = array()); /** * Renders a FOFForm and returns the corresponding HTML * * @param FOFForm &$form The form to render * @param FOFModel $model The model providing our data * @param FOFInput $input The input object * @param string $formType The form type: edit, browse or read * @param boolean $raw If true, the raw form fields rendering (without the surrounding form tag) is returned. * * @return string The HTML rendering of the form */ public function renderForm(FOFForm &$form, FOFModel $model, FOFInput $input, $formType = null, $raw = false) { if (is_null($formType)) { $formType = $form->getAttribute('type', 'edit'); } else { $formType = strtolower($formType); } switch ($formType) { case 'browse': return $this->renderFormBrowse($form, $model, $input); break; case 'read': if ($raw) { return $this->renderFormRaw($form, $model, $input, 'read'); } else { return $this->renderFormRead($form, $model, $input); } break; default: if ($raw) { return $this->renderFormRaw($form, $model, $input, 'edit'); } else { return $this->renderFormEdit($form, $model, $input); } break; } } /** * Renders the submenu (link bar) for a category view when it is used in a * extension * * Note: this function has to be called from the addSubmenu function in * the ExtensionNameHelper class located in * administrator/components/com_ExtensionName/helpers/Extensionname.php * * Example Code: * * class ExtensionNameHelper * { * public static function addSubmenu($vName) * { * // Load FOF * include_once JPATH_LIBRARIES . '/fof/include.php'; * * if (!defined('FOF_INCLUDED')) * { * JError::raiseError('500', 'FOF is not installed'); * } * * if (version_compare(JVERSION, '3.0', 'ge')) * { * $strapper = new FOFRenderJoomla3; * } * else * { * $strapper = new FOFRenderJoomla; * } * * $strapper->renderCategoryLinkbar('com_babioonevent'); * } * } * * @param string $extension The name of the extension * @param array $config Extra configuration variables for the toolbar * * @return void */ public function renderCategoryLinkbar($extension, $config = array()) { // On command line don't do anything if (FOFPlatform::getInstance()->isCli()) { return; } // Do not render a category submenu unless we are in the the admin area if (!FOFPlatform::getInstance()->isBackend()) { return; } $toolbar = FOFToolbar::getAnInstance($extension, $config); $toolbar->renderSubmenu(); $this->renderLinkbarItems($toolbar); } /** * Renders a FOFForm for a Browse view and returns the corresponding HTML * * @param FOFForm &$form The form to render * @param FOFModel $model The model providing our data * @param FOFInput $input The input object * * @return string The HTML rendering of the form */ abstract protected function renderFormBrowse(FOFForm &$form, FOFModel $model, FOFInput $input); /** * Renders a FOFForm for a Read view and returns the corresponding HTML * * @param FOFForm &$form The form to render * @param FOFModel $model The model providing our data * @param FOFInput $input The input object * * @return string The HTML rendering of the form */ abstract protected function renderFormRead(FOFForm &$form, FOFModel $model, FOFInput $input); /** * Renders a FOFForm for an Edit view and returns the corresponding HTML * * @param FOFForm &$form The form to render * @param FOFModel $model The model providing our data * @param FOFInput $input The input object * * @return string The HTML rendering of the form */ abstract protected function renderFormEdit(FOFForm &$form, FOFModel $model, FOFInput $input); /** * Renders a raw FOFForm and returns the corresponding HTML * * @param FOFForm &$form The form to render * @param FOFModel $model The model providing our data * @param FOFInput $input The input object * @param string $formType The form type e.g. 'edit' or 'read' * * @return string The HTML rendering of the form */ abstract protected function renderFormRaw(FOFForm &$form, FOFModel $model, FOFInput $input, $formType); /** * Renders a raw fieldset of a FOFForm and returns the corresponding HTML * * @TODO: Convert to an abstract method or interface at FOF3 * * @param stdClass &$fieldset The fieldset to render * @param FOFForm &$form The form to render * @param FOFModel $model The model providing our data * @param FOFInput $input The input object * @param string $formType The form type e.g. 'edit' or 'read' * @param boolean $showHeader Should I render the fieldset's header? * * @return string The HTML rendering of the fieldset */ protected function renderFieldset(stdClass &$fieldset, FOFForm &$form, FOFModel $model, FOFInput $input, $formType, $showHeader = true) { } /** * Renders a label for a fieldset. * * @TODO: Convert to an abstract method or interface at FOF3 * * @param object $field The field of the label to render * @param FOFForm &$form The form to render * @param string $title The title of the label * * @return string The rendered label */ protected function renderFieldsetLabel($field, FOFForm &$form, $title) { } /** * Checks if the fieldset defines a tab pane * * @param SimpleXMLElement $fieldset * * @return boolean */ protected function isTabFieldset($fieldset) { if (!isset($fieldset->class) || !$fieldset->class) { return false; } $class = $fieldset->class; $classes = explode(' ', $class); if (!in_array('tab-pane', $classes)) { return false; } else { return in_array('active', $classes) ? 2 : 1; } } } PK *\.]Q�\�G� G� fof/render/strapper.phpnu &1i� <?php /** * @package FrameworkOnFramework * @subpackage render * @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('FOF_INCLUDED') or die; /** * Akeeba Strapper view renderer class. * * @package FrameworkOnFramework * @since 2.0 */ class FOFRenderStrapper extends FOFRenderAbstract { /** * Public constructor. Determines the priority of this class and if it should be enabled */ public function __construct() { $this->priority = 60; $this->enabled = class_exists('AkeebaStrapper'); } /** * Echoes any HTML to show before the view template * * @param string $view The current view * @param string $task The current task * @param FOFInput $input The input array (request parameters) * @param array $config The view configuration array * * @return void */ public function preRender($view, $task, $input, $config = array()) { $format = $input->getCmd('format', 'html'); if (empty($format)) { $format = 'html'; } if ($format != 'html') { return; } $platform = FOFPlatform::getInstance(); if ($platform->isCli()) { return; } if (version_compare(JVERSION, '3.0.0', 'lt')) { JHtml::_('behavior.framework'); } else { if (version_compare(JVERSION, '3.3.0', 'ge')) { JHtml::_('behavior.core'); } else { JHtml::_('behavior.framework', true); } JHtml::_('jquery.framework'); } // Wrap output in various classes $version = new JVersion; $versionParts = explode('.', $version->RELEASE); $minorVersion = str_replace('.', '', $version->RELEASE); $majorVersion = array_shift($versionParts); if ($platform->isBackend()) { $area = $platform->isBackend() ? 'admin' : 'site'; $option = $input->getCmd('option', ''); $view = $input->getCmd('view', ''); $layout = $input->getCmd('layout', ''); $task = $input->getCmd('task', ''); $classes = array( 'joomla-version-' . $majorVersion, 'joomla-version-' . $minorVersion, $area, $option, 'view-' . $view, 'layout-' . $layout, 'task-' . $task, // We have a floating sidebar, they said. It looks great, they said. They must've been blind, I say! 'j-toggle-main', 'j-toggle-transition', 'span12', ); } elseif ($platform->isFrontend()) { // @TODO: Remove the frontend Joomla! version classes in FOF 3 $classes = array( 'joomla-version-' . $majorVersion, 'joomla-version-' . $minorVersion, ); } // Wrap output in divs echo '<div id="akeeba-bootstrap" class="' . implode($classes, ' ') . "\">\n"; echo "<div class=\"akeeba-bootstrap\">\n"; echo "<div class=\"row-fluid\">\n"; // Render submenu and toolbar (only if asked to) if ($input->getBool('render_toolbar', true)) { $this->renderButtons($view, $task, $input, $config); $this->renderLinkbar($view, $task, $input, $config); } } /** * Echoes any HTML to show after the view template * * @param string $view The current view * @param string $task The current task * @param FOFInput $input The input array (request parameters) * @param array $config The view configuration array * * @return void */ public function postRender($view, $task, $input, $config = array()) { $format = $input->getCmd('format', 'html'); if ($format != 'html' || FOFPlatform::getInstance()->isCli()) { return; } if (!FOFPlatform::getInstance()->isCli() && version_compare(JVERSION, '3.0', 'ge')) { $sidebarEntries = JHtmlSidebar::getEntries(); if (!empty($sidebarEntries)) { echo '</div>'; } } echo "</div>\n"; // Closes row-fluid div echo "</div>\n"; // Closes akeeba-bootstrap div echo "</div>\n"; // Closes joomla-version div } /** * Loads the validation script for an edit form * * @param FOFForm &$form The form we are rendering * * @return void */ protected function loadValidationScript(FOFForm &$form) { $message = $form->getView()->escape(JText::_('JGLOBAL_VALIDATION_FORM_FAILED')); $js = <<<JS Joomla.submitbutton = function(task) { if (task == 'cancel' || document.formvalidator.isValid(document.id('adminForm'))) { Joomla.submitform(task, document.getElementById('adminForm')); } else { alert('$message'); } }; JS; $document = FOFPlatform::getInstance()->getDocument(); if ($document instanceof JDocument) { $document->addScriptDeclaration($js); } } /** * Renders the submenu (link bar) * * @param string $view The active view name * @param string $task The current task * @param FOFInput $input The input object * @param array $config Extra configuration variables for the toolbar * * @return void */ protected function renderLinkbar($view, $task, $input, $config = array()) { $style = 'classic'; if (array_key_exists('linkbar_style', $config)) { $style = $config['linkbar_style']; } if (!version_compare(JVERSION, '3.0', 'ge')) { $style = 'classic'; } switch ($style) { case 'joomla': $this->renderLinkbar_joomla($view, $task, $input); break; case 'classic': default: $this->renderLinkbar_classic($view, $task, $input); break; } } /** * Renders the submenu (link bar) in FOF's classic style, using a Bootstrapped * tab bar. * * @param string $view The active view name * @param string $task The current task * @param FOFInput $input The input object * @param array $config Extra configuration variables for the toolbar * * @return void */ protected function renderLinkbar_classic($view, $task, $input, $config = array()) { if (FOFPlatform::getInstance()->isCli()) { return; } // Do not render a submenu unless we are in the the admin area $toolbar = FOFToolbar::getAnInstance($input->getCmd('option', 'com_foobar'), $config); $renderFrontendSubmenu = $toolbar->getRenderFrontendSubmenu(); if (!FOFPlatform::getInstance()->isBackend() && !$renderFrontendSubmenu) { return; } $links = $toolbar->getLinks(); if (!empty($links)) { echo "<ul class=\"nav nav-tabs\">\n"; foreach ($links as $link) { $dropdown = false; if (array_key_exists('dropdown', $link)) { $dropdown = $link['dropdown']; } if ($dropdown) { echo "<li"; $class = 'dropdown'; if ($link['active']) { $class .= ' active'; } echo ' class="' . $class . '">'; echo '<a class="dropdown-toggle" data-toggle="dropdown" href="#">'; if ($link['icon']) { echo "<i class=\"icon icon-" . $link['icon'] . "\"></i>"; } echo $link['name']; echo '<b class="caret"></b>'; echo '</a>'; echo "\n<ul class=\"dropdown-menu\">"; foreach ($link['items'] as $item) { echo "<li"; if ($item['active']) { echo ' class="active"'; } echo ">"; if ($item['icon']) { echo "<i class=\"icon icon-" . $item['icon'] . "\"></i>"; } if ($item['link']) { echo "<a href=\"" . $item['link'] . "\">" . $item['name'] . "</a>"; } else { echo $item['name']; } echo "</li>"; } echo "</ul>\n"; } else { echo "<li"; if ($link['active']) { echo ' class="active"'; } echo ">"; if ($link['icon']) { echo "<i class=\"icon icon-" . $link['icon'] . "\"></i>"; } if ($link['link']) { echo "<a href=\"" . $link['link'] . "\">" . $link['name'] . "</a>"; } else { echo $link['name']; } } echo "</li>\n"; } echo "</ul>\n"; } } /** * Renders the submenu (link bar) using Joomla!'s style. On Joomla! 2.5 this * is a list of bar separated links, on Joomla! 3 it's a sidebar at the * left-hand side of the page. * * @param string $view The active view name * @param string $task The current task * @param FOFInput $input The input object * @param array $config Extra configuration variables for the toolbar * * @return void */ protected function renderLinkbar_joomla($view, $task, $input, $config = array()) { // On command line don't do anything if (FOFPlatform::getInstance()->isCli()) { return; } // Do not render a submenu unless we are in the the admin area $toolbar = FOFToolbar::getAnInstance($input->getCmd('option', 'com_foobar'), $config); $renderFrontendSubmenu = $toolbar->getRenderFrontendSubmenu(); if (!FOFPlatform::getInstance()->isBackend() && !$renderFrontendSubmenu) { return; } $this->renderLinkbarItems($toolbar); } /** * do the rendering job for the linkbar * * @param FOFToolbar $toolbar A toolbar object * * @return void */ protected function renderLinkbarItems($toolbar) { $links = $toolbar->getLinks(); if (!empty($links)) { foreach ($links as $link) { JHtmlSidebar::addEntry($link['name'], $link['link'], $link['active']); $dropdown = false; if (array_key_exists('dropdown', $link)) { $dropdown = $link['dropdown']; } if ($dropdown) { foreach ($link['items'] as $item) { JHtmlSidebar::addEntry('– ' . $item['name'], $item['link'], $item['active']); } } } } } /** * Renders the toolbar buttons * * @param string $view The active view name * @param string $task The current task * @param FOFInput $input The input object * @param array $config Extra configuration variables for the toolbar * * @return void */ protected function renderButtons($view, $task, $input, $config = array()) { if (FOFPlatform::getInstance()->isCli()) { return; } // Do not render buttons unless we are in the the frontend area and we are asked to do so $toolbar = FOFToolbar::getAnInstance($input->getCmd('option', 'com_foobar'), $config); $renderFrontendButtons = $toolbar->getRenderFrontendButtons(); // Load main backend language, in order to display toolbar strings // (JTOOLBAR_BACK, JTOOLBAR_PUBLISH etc etc) FOFPlatform::getInstance()->loadTranslations('joomla'); if (FOFPlatform::getInstance()->isBackend() || !$renderFrontendButtons) { return; } $bar = JToolbar::getInstance('toolbar'); $items = $bar->getItems(); $substitutions = array( 'icon-32-new' => 'icon-plus', 'icon-32-publish' => 'icon-eye-open', 'icon-32-unpublish' => 'icon-eye-close', 'icon-32-delete' => 'icon-trash', 'icon-32-edit' => 'icon-edit', 'icon-32-copy' => 'icon-th-large', 'icon-32-cancel' => 'icon-remove', 'icon-32-back' => 'icon-circle-arrow-left', 'icon-32-apply' => 'icon-ok', 'icon-32-save' => 'icon-hdd', 'icon-32-save-new' => 'icon-repeat', ); if(isset(JFactory::getApplication()->JComponentTitle)) { $title = JFactory::getApplication()->JComponentTitle; } else { $title = ''; } $html = array(); $actions = array(); // For BC we have to use the same id we're using inside other renderers (FOFHeaderHolder) //$html[] = '<div class="well" id="' . $bar->getName() . '">'; $html[] = '<div class="well" id="FOFHeaderHolder">'; $html[] = '<div class="titleHolder">'.$title.'</div>'; $html[] = '<div class="buttonsHolder">'; foreach ($items as $node) { $type = $node[0]; $button = $bar->loadButtonType($type); if ($button !== false) { if (method_exists($button, 'fetchId')) { $id = call_user_func_array(array(&$button, 'fetchId'), $node); } else { $id = null; } $action = call_user_func_array(array(&$button, 'fetchButton'), $node); $action = str_replace('class="toolbar"', 'class="toolbar btn"', $action); $action = str_replace('<span ', '<i ', $action); $action = str_replace('</span>', '</i>', $action); $action = str_replace(array_keys($substitutions), array_values($substitutions), $action); $actions[] = $action; } } $html = array_merge($html, $actions); $html[] = '</div>'; $html[] = '</div>'; echo implode("\n", $html); } /** * Renders a FOFForm for a Browse view and returns the corresponding HTML * * @param FOFForm &$form The form to render * @param FOFModel $model The model providing our data * @param FOFInput $input The input object * * @return string The HTML rendering of the form */ protected function renderFormBrowse(FOFForm &$form, FOFModel $model, FOFInput $input) { $html = ''; JHtml::_('behavior.multiselect'); // Joomla! 3.0+ support if (version_compare(JVERSION, '3.0', 'ge')) { JHtml::_('bootstrap.tooltip'); JHtml::_('dropdown.init'); JHtml::_('formbehavior.chosen', 'select'); $view = $form->getView(); $order = $view->escape($view->getLists()->order); $html .= <<<HTML <script type="text/javascript"> Joomla.orderTable = function() { table = document.getElementById("sortTable"); direction = document.getElementById("directionTable"); order = table.options[table.selectedIndex].value; if (order != '$order') { dirn = 'asc'; } else { dirn = direction.options[direction.selectedIndex].value; } Joomla.tableOrdering(order, dirn); }; </script> HTML; } else { JHtml::_('behavior.tooltip'); } // Getting all header row elements $headerFields = $form->getHeaderset(); // Get form parameters $show_header = $form->getAttribute('show_header', 1); $show_filters = $form->getAttribute('show_filters', 1); $show_pagination = $form->getAttribute('show_pagination', 1); $norows_placeholder = $form->getAttribute('norows_placeholder', ''); // Joomla! 3.0 sidebar support if (version_compare(JVERSION, '3.0', 'gt')) { $form_class = ''; if ($show_filters) { JHtmlSidebar::setAction("index.php?option=" . $input->getCmd('option') . "&view=" . FOFInflector::pluralize($input->getCmd('view')) ); } // Reorder the fields with ordering first $tmpFields = array(); $i = 1; foreach ($headerFields as $tmpField) { if ($tmpField instanceof FOFFormHeaderOrdering) { $tmpFields[0] = $tmpField; } else { $tmpFields[$i] = $tmpField; } $i++; } $headerFields = $tmpFields; ksort($headerFields, SORT_NUMERIC); } else { $form_class = 'class="form-horizontal"'; } // Pre-render the header and filter rows $header_html = ''; $filter_html = ''; $sortFields = array(); if ($show_header || $show_filters) { foreach ($headerFields as $headerField) { $header = $headerField->header; $filter = $headerField->filter; $buttons = $headerField->buttons; $options = $headerField->options; $sortable = $headerField->sortable; $tdwidth = $headerField->tdwidth; // Under Joomla! < 3.0 we can't have filter-only fields if (version_compare(JVERSION, '3.0', 'lt') && empty($header)) { continue; } // If it's a sortable field, add to the list of sortable fields if ($sortable) { $sortFields[$headerField->name] = JText::_($headerField->label); } // Get the table data width, if set if (!empty($tdwidth)) { $tdwidth = 'width="' . $tdwidth . '"'; } else { $tdwidth = ''; } if (!empty($header)) { $header_html .= "\t\t\t\t\t<th $tdwidth>" . PHP_EOL; $header_html .= "\t\t\t\t\t\t" . $header; $header_html .= "\t\t\t\t\t</th>" . PHP_EOL; } if (version_compare(JVERSION, '3.0', 'ge')) { // Joomla! 3.0 or later if (!empty($filter)) { $filter_html .= '<div class="filter-search btn-group pull-left">' . "\n"; $filter_html .= "\t" . '<label for="title" class="element-invisible">'; $filter_html .= JText::_($headerField->label); $filter_html .= "</label>\n"; $filter_html .= "\t$filter\n"; $filter_html .= "</div>\n"; if (!empty($buttons)) { $filter_html .= '<div class="btn-group pull-left hidden-phone">' . "\n"; $filter_html .= "\t$buttons\n"; $filter_html .= '</div>' . "\n"; } } elseif (!empty($options)) { $label = $headerField->label; JHtmlSidebar::addFilter( '- ' . JText::_($label) . ' -', (string) $headerField->name, JHtml::_( 'select.options', $options, 'value', 'text', $model->getState($headerField->name, ''), true ) ); } } else { // Joomla! 2.5 $filter_html .= "\t\t\t\t\t<td>" . PHP_EOL; if (!empty($filter)) { $filter_html .= "\t\t\t\t\t\t$filter" . PHP_EOL; if (!empty($buttons)) { $filter_html .= '<div class="btn-group hidden-phone">' . PHP_EOL; $filter_html .= "\t\t\t\t\t\t$buttons" . PHP_EOL; $filter_html .= '</div>' . PHP_EOL; } } elseif (!empty($options)) { $label = $headerField->label; $emptyOption = JHtml::_('select.option', '', '- ' . JText::_($label) . ' -'); array_unshift($options, $emptyOption); $attribs = array( 'onchange' => 'document.adminForm.submit();' ); $filter = JHtml::_('select.genericlist', $options, $headerField->name, $attribs, 'value', 'text', $headerField->value, false, true); $filter_html .= "\t\t\t\t\t\t$filter" . PHP_EOL; } $filter_html .= "\t\t\t\t\t</td>" . PHP_EOL; } } } // Start the form $filter_order = $form->getView()->getLists()->order; $filter_order_Dir = $form->getView()->getLists()->order_Dir; $actionUrl = FOFPlatform::getInstance()->isBackend() ? 'index.php' : JUri::root().'index.php'; if (FOFPlatform::getInstance()->isFrontend() && ($input->getCmd('Itemid', 0) != 0)) { $itemid = $input->getCmd('Itemid', 0); $uri = new JUri($actionUrl); if ($itemid) { $uri->setVar('Itemid', $itemid); } $actionUrl = JRoute::_($uri->toString()); } $html .= '<form action="'.$actionUrl.'" method="post" name="adminForm" id="adminForm" ' . $form_class . '>' . PHP_EOL; if (version_compare(JVERSION, '3.0', 'ge')) { // Joomla! 3.0+ // Get and output the sidebar, if present $sidebar = JHtmlSidebar::render(); if ($show_filters && !empty($sidebar)) { $html .= '<div id="j-sidebar-container" class="span2">' . "\n"; $html .= "\t$sidebar\n"; $html .= "</div>\n"; $html .= '<div id="j-main-container" class="span10">' . "\n"; } else { $html .= '<div id="j-main-container">' . "\n"; } // Render header search fields, if the header is enabled if ($show_header) { $html .= "\t" . '<div id="filter-bar" class="btn-toolbar">' . "\n"; $html .= "$filter_html\n"; if ($show_pagination) { // Render the pagination rows per page selection box, if the pagination is enabled $html .= "\t" . '<div class="btn-group pull-right hidden-phone">' . "\n"; $html .= "\t\t" . '<label for="limit" class="element-invisible">' . JText::_('JFIELD_PLG_SEARCH_SEARCHLIMIT_DESC') . '</label>' . "\n"; $html .= "\t\t" . $model->getPagination()->getLimitBox() . "\n"; $html .= "\t" . '</div>' . "\n"; } if (!empty($sortFields)) { // Display the field sort order $asc_sel = ($view->getLists()->order_Dir == 'asc') ? 'selected="selected"' : ''; $desc_sel = ($view->getLists()->order_Dir == 'desc') ? 'selected="selected"' : ''; $html .= "\t" . '<div class="btn-group pull-right hidden-phone">' . "\n"; $html .= "\t\t" . '<label for="directionTable" class="element-invisible">' . JText::_('JFIELD_ORDERING_DESC') . '</label>' . "\n"; $html .= "\t\t" . '<select name="directionTable" id="directionTable" class="input-medium" onchange="Joomla.orderTable()">' . "\n"; $html .= "\t\t\t" . '<option value="">' . JText::_('JFIELD_ORDERING_DESC') . '</option>' . "\n"; $html .= "\t\t\t" . '<option value="asc" ' . $asc_sel . '>' . JText::_('JGLOBAL_ORDER_ASCENDING') . '</option>' . "\n"; $html .= "\t\t\t" . '<option value="desc" ' . $desc_sel . '>' . JText::_('JGLOBAL_ORDER_DESCENDING') . '</option>' . "\n"; $html .= "\t\t" . '</select>' . "\n"; $html .= "\t" . '</div>' . "\n\n"; // Display the sort fields $html .= "\t" . '<div class="btn-group pull-right">' . "\n"; $html .= "\t\t" . '<label for="sortTable" class="element-invisible">' . JText::_('JGLOBAL_SORT_BY') . '</label>' . "\n"; $html .= "\t\t" . '<select name="sortTable" id="sortTable" class="input-medium" onchange="Joomla.orderTable()">' . "\n"; $html .= "\t\t\t" . '<option value="">' . JText::_('JGLOBAL_SORT_BY') . '</option>' . "\n"; $html .= "\t\t\t" . JHtml::_('select.options', $sortFields, 'value', 'text', $view->getLists()->order) . "\n"; $html .= "\t\t" . '</select>' . "\n"; $html .= "\t" . '</div>' . "\n"; } $html .= "\t</div>\n\n"; $html .= "\t" . '<div class="clearfix"> </div>' . "\n\n"; } } // Start the table output $html .= "\t\t" . '<table class="table table-striped" id="itemsList">' . PHP_EOL; // Open the table header region if required if ($show_header || ($show_filters && version_compare(JVERSION, '3.0', 'lt'))) { $html .= "\t\t\t<thead>" . PHP_EOL; } // Render the header row, if enabled if ($show_header) { $html .= "\t\t\t\t<tr>" . PHP_EOL; $html .= $header_html; $html .= "\t\t\t\t</tr>" . PHP_EOL; } // Render filter row if enabled if ($show_filters && version_compare(JVERSION, '3.0', 'lt')) { $html .= "\t\t\t\t<tr>"; $html .= $filter_html; $html .= "\t\t\t\t</tr>"; } // Close the table header region if required if ($show_header || ($show_filters && version_compare(JVERSION, '3.0', 'lt'))) { $html .= "\t\t\t</thead>" . PHP_EOL; } // Loop through rows and fields, or show placeholder for no rows $html .= "\t\t\t<tbody>" . PHP_EOL; $fields = $form->getFieldset('items'); $num_columns = count($fields); $items = $model->getItemList(); if ($count = count($items)) { $m = 1; foreach ($items as $i => $item) { $table_item = $model->getTable(); $table_item->reset(); $table_item->bind($item); $form->bind($item); $m = 1 - $m; $class = 'row' . $m; $html .= "\t\t\t\t<tr class=\"$class\">" . PHP_EOL; $fields = $form->getFieldset('items'); // Reorder the fields to have ordering first if (version_compare(JVERSION, '3.0', 'gt')) { $tmpFields = array(); $j = 1; foreach ($fields as $tmpField) { if ($tmpField instanceof FOFFormFieldOrdering) { $tmpFields[0] = $tmpField; } else { $tmpFields[$j] = $tmpField; } $j++; } $fields = $tmpFields; ksort($fields, SORT_NUMERIC); } foreach ($fields as $field) { $field->rowid = $i; $field->item = $table_item; $labelClass = $field->labelClass ? $field->labelClass : $field->labelclass; // Joomla! 2.5/3.x use different case for the same name $class = $labelClass ? 'class ="' . $labelClass . '"' : ''; $html .= "\t\t\t\t\t<td $class>" . $field->getRepeatable() . '</td>' . PHP_EOL; } $html .= "\t\t\t\t</tr>" . PHP_EOL; } } elseif ($norows_placeholder) { $html .= "\t\t\t\t<tr><td colspan=\"$num_columns\">"; $html .= JText::_($norows_placeholder); $html .= "</td></tr>\n"; } $html .= "\t\t\t</tbody>" . PHP_EOL; // Render the pagination bar, if enabled, on J! 2.5 if ($show_pagination && version_compare(JVERSION, '3.0', 'lt')) { $pagination = $model->getPagination(); $html .= "\t\t\t<tfoot>" . PHP_EOL; $html .= "\t\t\t\t<tr><td colspan=\"$num_columns\">"; if (($pagination->total > 0)) { $html .= $pagination->getListFooter(); } $html .= "</td></tr>\n"; $html .= "\t\t\t</tfoot>" . PHP_EOL; } // End the table output $html .= "\t\t" . '</table>' . PHP_EOL; // Render the pagination bar, if enabled, on J! 3.0+ if ($show_pagination && version_compare(JVERSION, '3.0', 'ge')) { $html .= $model->getPagination()->getListFooter(); } // Close the wrapper element div on Joomla! 3.0+ if (version_compare(JVERSION, '3.0', 'ge')) { $html .= "</div>\n"; } $html .= "\t" . '<input type="hidden" name="option" value="' . $input->getCmd('option') . '" />' . PHP_EOL; $html .= "\t" . '<input type="hidden" name="view" value="' . FOFInflector::pluralize($input->getCmd('view')) . '" />' . PHP_EOL; $html .= "\t" . '<input type="hidden" name="task" value="' . $input->getCmd('task', 'browse') . '" />' . PHP_EOL; $html .= "\t" . '<input type="hidden" name="layout" value="' . $input->getCmd('layout', '') . '" />' . PHP_EOL; // The id field is required in Joomla! 3 front-end to prevent the pagination limit box from screwing it up. Huh!! if (version_compare(JVERSION, '3.0', 'ge') && FOFPlatform::getInstance()->isFrontend()) { $html .= "\t" . '<input type="hidden" name="id" value="' . $input->getCmd('id', '') . '" />' . PHP_EOL; } $html .= "\t" . '<input type="hidden" name="boxchecked" value="" />' . PHP_EOL; $html .= "\t" . '<input type="hidden" name="hidemainmenu" value="" />' . PHP_EOL; $html .= "\t" . '<input type="hidden" name="filter_order" value="' . $filter_order . '" />' . PHP_EOL; $html .= "\t" . '<input type="hidden" name="filter_order_Dir" value="' . $filter_order_Dir . '" />' . PHP_EOL; $html .= "\t" . '<input type="hidden" name="' . JFactory::getSession()->getFormToken() . '" value="1" />' . PHP_EOL; // End the form $html .= '</form>' . PHP_EOL; return $html; } /** * Renders a FOFForm for a Read view and returns the corresponding HTML * * @param FOFForm &$form The form to render * @param FOFModel $model The model providing our data * @param FOFInput $input The input object * * @return string The HTML rendering of the form */ protected function renderFormRead(FOFForm &$form, FOFModel $model, FOFInput $input) { $html = $this->renderFormRaw($form, $model, $input, 'read'); return $html; } /** * Renders a FOFForm for an Edit view and returns the corresponding HTML * * @param FOFForm &$form The form to render * @param FOFModel $model The model providing our data * @param FOFInput $input The input object * * @return string The HTML rendering of the form */ protected function renderFormEdit(FOFForm &$form, FOFModel $model, FOFInput $input) { // Get the key for this model's table $key = $model->getTable()->getKeyName(); $keyValue = $model->getId(); $html = ''; $validate = strtolower($form->getAttribute('validate')); if (in_array($validate, array('true', 'yes', '1', 'on'))) { JHtml::_('behavior.formvalidation'); $class = ' form-validate'; $this->loadValidationScript($form); } else { $class = ''; } // Check form enctype. Use enctype="multipart/form-data" to upload binary files in your form. $template_form_enctype = $form->getAttribute('enctype'); if (!empty($template_form_enctype)) { $enctype = ' enctype="' . $form->getAttribute('enctype') . '" '; } else { $enctype = ''; } // Check form name. Use name="yourformname" to modify the name of your form. $formname = $form->getAttribute('name'); if (empty($formname)) { $formname = 'adminForm'; } // Check form ID. Use id="yourformname" to modify the id of your form. $formid = $form->getAttribute('name'); if (empty($formid)) { $formid = 'adminForm'; } // Check if we have a custom task $customTask = $form->getAttribute('customTask'); if (empty($customTask)) { $customTask = ''; } // Get the form action URL $actionUrl = FOFPlatform::getInstance()->isBackend() ? 'index.php' : JUri::root().'index.php'; if (FOFPlatform::getInstance()->isFrontend() && ($input->getCmd('Itemid', 0) != 0)) { $itemid = $input->getCmd('Itemid', 0); $uri = new JUri($actionUrl); if ($itemid) { $uri->setVar('Itemid', $itemid); } $actionUrl = JRoute::_($uri->toString()); } $html .= '<form action="'.$actionUrl.'" method="post" name="' . $formname . '" id="' . $formid . '"' . $enctype . ' class="form-horizontal' . $class . '">' . PHP_EOL; $html .= "\t" . '<input type="hidden" name="option" value="' . $input->getCmd('option') . '" />' . PHP_EOL; $html .= "\t" . '<input type="hidden" name="view" value="' . $input->getCmd('view', 'edit') . '" />' . PHP_EOL; $html .= "\t" . '<input type="hidden" name="task" value="' . $customTask . '" />' . PHP_EOL; $html .= "\t" . '<input type="hidden" name="' . $key . '" value="' . $keyValue . '" />' . PHP_EOL; $html .= "\t" . '<input type="hidden" name="' . JFactory::getSession()->getFormToken() . '" value="1" />' . PHP_EOL; $html .= $this->renderFormRaw($form, $model, $input, 'edit'); $html .= '</form>'; return $html; } /** * Renders a raw FOFForm and returns the corresponding HTML * * @param FOFForm &$form The form to render * @param FOFModel $model The model providing our data * @param FOFInput $input The input object * @param string $formType The form type e.g. 'edit' or 'read' * * @return string The HTML rendering of the form */ protected function renderFormRaw(FOFForm &$form, FOFModel $model, FOFInput $input, $formType) { $html = ''; $tabHtml = array(); // Do we have a tabbed form? $isTabbed = $form->getAttribute('tabbed', '0'); $isTabbed = in_array($isTabbed, array('true', 'yes', 'on', '1')); foreach ($form->getFieldsets() as $fieldset) { if ($isTabbed && $this->isTabFieldset($fieldset)) { continue; } elseif ($isTabbed && isset($fieldset->innertab)) { $inTab = $fieldset->innertab; } else { $inTab = '__outer'; } $tabHtml[$inTab][] = $this->renderFieldset($fieldset, $form, $model, $input, $formType, false); } // If the form is tabbed, render the tabs bars if ($isTabbed) { $html .= '<ul class="nav nav-tabs">' . PHP_EOL; foreach ($form->getFieldsets() as $fieldset) { // Only create tabs for tab fieldsets $isTabbedFieldset = $this->isTabFieldset($fieldset); if (!$isTabbedFieldset) { continue; } // Only create tabs if we do have a label if (!isset($fieldset->label) || empty($fieldset->label)) { continue; } $label = JText::_($fieldset->label); $name = $fieldset->name; $liClass = ($isTabbedFieldset == 2) ? 'class="active"' : ''; $html .= "<li $liClass><a href=\"#$name\" data-toggle=\"tab\">$label</a></li>" . PHP_EOL; } $html .= '</ul>' . "\n\n<div class=\"tab-content\">" . PHP_EOL; foreach ($form->getFieldsets() as $fieldset) { if (!$this->isTabFieldset($fieldset)) { continue; } $html .= $this->renderFieldset($fieldset, $form, $model, $input, $formType, false, $tabHtml); } $html .= "</div>\n"; } if (isset($tabHtml['__outer'])) { $html .= implode('', $tabHtml['__outer']); } return $html; } /** * Renders a raw fieldset of a FOFForm and returns the corresponding HTML * * @param stdClass &$fieldset The fieldset to render * @param FOFForm &$form The form to render * @param FOFModel $model The model providing our data * @param FOFInput $input The input object * @param string $formType The form type e.g. 'edit' or 'read' * @param boolean $showHeader Should I render the fieldset's header? * * @return string The HTML rendering of the fieldset */ protected function renderFieldset(stdClass &$fieldset, FOFForm &$form, FOFModel $model, FOFInput $input, $formType, $showHeader = true, &$innerHtml = null) { $html = ''; $fields = $form->getFieldset($fieldset->name); if (isset($fieldset->class)) { $class = 'class="' . $fieldset->class . '"'; } else { $class = ''; } if (isset($innerHtml[$fieldset->name])) { $innerclass = isset($fieldset->innerclass) ? ' class="' . $fieldset->innerclass . '"' : ''; $html .= "\t" . '<div id="' . $fieldset->name . '" ' . $class . '>' . PHP_EOL; $html .= "\t\t" . '<div' . $innerclass . '>' . PHP_EOL; } else { $html .= "\t" . '<div id="' . $fieldset->name . '" ' . $class . '>' . PHP_EOL; } $isTabbedFieldset = $this->isTabFieldset($fieldset); if (isset($fieldset->label) && !empty($fieldset->label) && !$isTabbedFieldset) { $html .= "\t\t" . '<h3>' . JText::_($fieldset->label) . '</h3>' . PHP_EOL; } foreach ($fields as $field) { $groupClass = $form->getFieldAttribute($field->fieldname, 'groupclass', '', $field->group); // Auto-generate label and description if needed // Field label $title = $form->getFieldAttribute($field->fieldname, 'label', '', $field->group); $emptylabel = $form->getFieldAttribute($field->fieldname, 'emptylabel', false, $field->group); if (empty($title) && !$emptylabel) { $model->getName(); $title = strtoupper($input->get('option') . '_' . $model->getName() . '_' . $field->id . '_LABEL'); } // Field description $description = $form->getFieldAttribute($field->fieldname, 'description', '', $field->group); /** * The following code is backwards incompatible. Most forms don't require a description in their form * fields. Having to use emptydescription="1" on each one of them is an overkill. Removed. */ /* $emptydescription = $form->getFieldAttribute($field->fieldname, 'emptydescription', false, $field->group); if (empty($description) && !$emptydescription) { $description = strtoupper($input->get('option') . '_' . $model->getName() . '_' . $field->id . '_DESC'); } */ if ($formType == 'read') { $inputField = $field->static; } elseif ($formType == 'edit') { $inputField = $field->input; } if (empty($title)) { $html .= "\t\t\t" . $inputField . PHP_EOL; if (!empty($description) && $formType == 'edit') { $html .= "\t\t\t\t" . '<span class="help-block">'; $html .= JText::_($description) . '</span>' . PHP_EOL; } } else { $html .= "\t\t\t" . '<div class="control-group ' . $groupClass . '">' . PHP_EOL; $html .= $this->renderFieldsetLabel($field, $form, $title); $html .= "\t\t\t\t" . '<div class="controls">' . PHP_EOL; $html .= "\t\t\t\t\t" . $inputField . PHP_EOL; if (!empty($description)) { $html .= "\t\t\t\t" . '<span class="help-block">'; $html .= JText::_($description) . '</span>' . PHP_EOL; } $html .= "\t\t\t\t" . '</div>' . PHP_EOL; $html .= "\t\t\t" . '</div>' . PHP_EOL; } } if (isset($innerHtml[$fieldset->name])) { $html .= "\t\t" . '</div>' . PHP_EOL; $html .= implode('', $innerHtml[$fieldset->name]) . PHP_EOL; $html .= "\t" . '</div>' . PHP_EOL; } else { $html .= "\t" . '</div>' . PHP_EOL; } return $html; } /** * Renders a label for a fieldset. * * @param object $field The field of the label to render * @param FOFForm &$form The form to render * @param string $title The title of the label * * @return string The rendered label */ protected function renderFieldsetLabel($field, FOFForm &$form, $title) { $html = ''; $labelClass = $field->labelClass ? $field->labelClass : $field->labelclass; // Joomla! 2.5/3.x use different case for the same name $required = $field->required; $tooltip = $form->getFieldAttribute($field->fieldname, 'tooltip', '', $field->group); if (!empty($tooltip)) { if (version_compare(JVERSION, '3.0', 'ge')) { static $loadedTooltipScript = false; if (!$loadedTooltipScript) { $js = <<<JS (function($) { $(document).ready(function() { $('.fof-tooltip').tooltip({placement: 'top'}); }); })(akeeba.jQuery); JS; $document = FOFPlatform::getInstance()->getDocument(); if ($document instanceof JDocument) { $document->addScriptDeclaration($js); } $loadedTooltipScript = true; } $tooltipText = '<strong>' . JText::_($title) . '</strong><br />' . JText::_($tooltip); $html .= "\t\t\t\t" . '<label class="control-label fof-tooltip ' . $labelClass . '" for="' . $field->id . '" title="' . $tooltipText . '" data-toggle="fof-tooltip">'; } else { // Joomla! 2.5 has a conflict with the jQueryUI tooltip, therefore we // have to use native Joomla! 2.5 tooltips JHtml::_('behavior.tooltip'); $tooltipText = JText::_($title) . '::' . JText::_($tooltip); $html .= "\t\t\t\t" . '<label class="control-label hasTip ' . $labelClass . '" for="' . $field->id . '" title="' . $tooltipText . '" rel="tooltip">'; } } else { $html .= "\t\t\t\t" . '<label class="control-label ' . $labelClass . '" for="' . $field->id . '">'; } $html .= JText::_($title); if ($required) { $html .= ' *'; } $html .= '</label>' . PHP_EOL; return $html; } } PK *\.] fof/render/.mad-rootnu �[��� PK *\.]!g}�T �T fof/render/joomla.phpnu &1i� <?php /** * @package FrameworkOnFramework * @subpackage render * @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('FOF_INCLUDED') or die; /** * Default Joomla! 1.5, 1.7, 2.5 view renderer class * * @package FrameworkOnFramework * @since 2.0 */ class FOFRenderJoomla extends FOFRenderAbstract { /** * Public constructor. Determines the priority of this class and if it should be enabled */ public function __construct() { $this->priority = 50; $this->enabled = true; } /** * Echoes any HTML to show before the view template * * @param string $view The current view * @param string $task The current task * @param FOFInput $input The input array (request parameters) * @param array $config The view configuration array * * @return void */ public function preRender($view, $task, $input, $config = array()) { $format = $input->getCmd('format', 'html'); if (empty($format)) { $format = 'html'; } if ($format != 'html') { return; } $platform = FOFPlatform::getInstance(); if ($platform->isCli()) { return; } if (version_compare(JVERSION, '3.0.0', 'lt')) { JHtml::_('behavior.framework'); } else { if (version_compare(JVERSION, '3.3.0', 'ge')) { JHtml::_('behavior.core'); } else { JHtml::_('behavior.framework', true); } JHtml::_('jquery.framework'); } // Wrap output in various classes $version = new JVersion; $versionParts = explode('.', $version->RELEASE); $minorVersion = str_replace('.', '', $version->RELEASE); $majorVersion = array_shift($versionParts); if ($platform->isBackend()) { $area = $platform->isBackend() ? 'admin' : 'site'; $option = $input->getCmd('option', ''); $view = $input->getCmd('view', ''); $layout = $input->getCmd('layout', ''); $task = $input->getCmd('task', ''); $classes = array( 'joomla-version-' . $majorVersion, 'joomla-version-' . $minorVersion, $area, $option, 'view-' . $view, 'layout-' . $layout, 'task-' . $task, ); } elseif ($platform->isFrontend()) { // @TODO: Remove the frontend Joomla! version classes in FOF 3 $classes = array( 'joomla-version-' . $majorVersion, 'joomla-version-' . $minorVersion, ); } echo '<div id="akeeba-renderjoomla" class="' . implode($classes, ' ') . "\">\n"; // Render submenu and toolbar (only if asked to) if ($input->getBool('render_toolbar', true)) { $this->renderButtons($view, $task, $input, $config); $this->renderLinkbar($view, $task, $input, $config); } } /** * Echoes any HTML to show after the view template * * @param string $view The current view * @param string $task The current task * @param FOFInput $input The input array (request parameters) * @param array $config The view configuration array * * @return void */ public function postRender($view, $task, $input, $config = array()) { $format = $input->getCmd('format', 'html'); if (empty($format)) { $format = 'html'; } if ($format != 'html') { return; } // Closing tag only if we're not in CLI if (FOFPlatform::getInstance()->isCli()) { return; } echo "</div>\n"; // Closes akeeba-renderjoomla div } /** * Renders a FOFForm for a Browse view and returns the corresponding HTML * * @param FOFForm &$form The form to render * @param FOFModel $model The model providing our data * @param FOFInput $input The input object * * @return string The HTML rendering of the form */ protected function renderFormBrowse(FOFForm &$form, FOFModel $model, FOFInput $input) { JHtml::_('behavior.multiselect'); // Getting all header row elements $headerFields = $form->getHeaderset(); // Start the form $html = ''; $filter_order = $form->getView()->getLists()->order; $filter_order_Dir = $form->getView()->getLists()->order_Dir; $actionUrl = FOFPlatform::getInstance()->isBackend() ? 'index.php' : JUri::root().'index.php'; if (FOFPlatform::getInstance()->isFrontend() && ($input->getCmd('Itemid', 0) != 0)) { $itemid = $input->getCmd('Itemid', 0); $uri = new JUri($actionUrl); if ($itemid) { $uri->setVar('Itemid', $itemid); } $actionUrl = JRoute::_($uri->toString()); } $html .= '<form action="'.$actionUrl.'" method="post" name="adminForm" id="adminForm">' . PHP_EOL; $html .= "\t" . '<input type="hidden" name="option" value="' . $input->getCmd('option') . '" />' . PHP_EOL; $html .= "\t" . '<input type="hidden" name="view" value="' . FOFInflector::pluralize($input->getCmd('view')) . '" />' . PHP_EOL; $html .= "\t" . '<input type="hidden" name="task" value="" />' . PHP_EOL; $html .= "\t" . '<input type="hidden" name="layout" value="' . $input->getCmd('layout', '') . '" />' . PHP_EOL; $html .= "\t" . '<input type="hidden" name="boxchecked" value="" />' . PHP_EOL; $html .= "\t" . '<input type="hidden" name="hidemainmenu" value="" />' . PHP_EOL; $html .= "\t" . '<input type="hidden" name="filter_order" value="' . $filter_order . '" />' . PHP_EOL; $html .= "\t" . '<input type="hidden" name="filter_order_Dir" value="' . $filter_order_Dir . '" />' . PHP_EOL; $html .= "\t" . '<input type="hidden" name="' . JFactory::getSession()->getFormToken() . '" value="1" />' . PHP_EOL; // Start the table output $html .= "\t\t" . '<table class="adminlist" id="adminList">' . PHP_EOL; // Get form parameters $show_header = $form->getAttribute('show_header', 1); $show_filters = $form->getAttribute('show_filters', 1); $show_pagination = $form->getAttribute('show_pagination', 1); $norows_placeholder = $form->getAttribute('norows_placeholder', ''); // Open the table header region if required if ($show_header || $show_filters) { $html .= "\t\t\t<thead>" . PHP_EOL; } // Pre-render the header and filter rows if ($show_header || $show_filters) { $header_html = ''; $filter_html = ''; foreach ($headerFields as $header) { // Make sure we have a header field. Under Joomla! 2.5 we cannot // render filter-only fields. $tmpHeader = $header->header; if (empty($tmpHeader)) { continue; } $tdwidth = $header->tdwidth; if (!empty($tdwidth)) { $tdwidth = 'width="' . $tdwidth . '"'; } else { $tdwidth = ''; } $header_html .= "\t\t\t\t\t<th $tdwidth>" . PHP_EOL; $header_html .= "\t\t\t\t\t\t" . $tmpHeader; $header_html .= "\t\t\t\t\t</th>" . PHP_EOL; $filter = $header->filter; $buttons = $header->buttons; $options = $header->options; $filter_html .= "\t\t\t\t\t<td>" . PHP_EOL; if (!empty($filter)) { $filter_html .= "\t\t\t\t\t\t$filter" . PHP_EOL; if (!empty($buttons)) { $filter_html .= "\t\t\t\t\t\t<nobr>$buttons</nobr>" . PHP_EOL; } } elseif (!empty($options)) { $label = $header->label; $emptyOption = JHtml::_('select.option', '', '- ' . JText::_($label) . ' -'); array_unshift($options, $emptyOption); $attribs = array( 'onchange' => 'document.adminForm.submit();' ); $filter = JHtml::_('select.genericlist', $options, $header->name, $attribs, 'value', 'text', $header->value, false, true); $filter_html .= "\t\t\t\t\t\t$filter" . PHP_EOL; } $filter_html .= "\t\t\t\t\t</td>" . PHP_EOL; } } // Render header if enabled if ($show_header) { $html .= "\t\t\t\t<tr>" . PHP_EOL; $html .= $header_html; $html .= "\t\t\t\t</tr>" . PHP_EOL; } // Render filter row if enabled if ($show_filters) { $html .= "\t\t\t\t<tr>"; $html .= $filter_html; $html .= "\t\t\t\t</tr>"; } // Close the table header region if required if ($show_header || $show_filters) { $html .= "\t\t\t</thead>" . PHP_EOL; } // Loop through rows and fields, or show placeholder for no rows $html .= "\t\t\t<tbody>" . PHP_EOL; $fields = $form->getFieldset('items'); $num_columns = count($fields); $items = $form->getModel()->getItemList(); if ($count = count($items)) { $m = 1; foreach ($items as $i => $item) { $table_item = $form->getModel()->getTable(); $table_item->reset(); $table_item->bind($item); $form->bind($item); $m = 1 - $m; $class = 'row' . $m; $html .= "\t\t\t\t<tr class=\"$class\">" . PHP_EOL; $fields = $form->getFieldset('items'); foreach ($fields as $field) { $field->rowid = $i; $field->item = $table_item; $labelClass = $field->labelClass ? $field->labelClass : $field->labelclass; // Joomla! 2.5/3.x use different case for the same name $class = $labelClass ? 'class ="' . $labelClass . '"' : ''; $html .= "\t\t\t\t\t<td $class>" . $field->getRepeatable() . '</td>' . PHP_EOL; } $html .= "\t\t\t\t</tr>" . PHP_EOL; } } elseif ($norows_placeholder) { $html .= "\t\t\t\t<tr><td colspan=\"$num_columns\">"; $html .= JText::_($norows_placeholder); $html .= "</td></tr>\n"; } $html .= "\t\t\t</tbody>" . PHP_EOL; // Render the pagination bar, if enabled if ($show_pagination) { $pagination = $form->getModel()->getPagination(); $html .= "\t\t\t<tfoot>" . PHP_EOL; $html .= "\t\t\t\t<tr><td colspan=\"$num_columns\">"; if (($pagination->total > 0)) { $html .= $pagination->getListFooter(); } $html .= "</td></tr>\n"; $html .= "\t\t\t</tfoot>" . PHP_EOL; } // End the table output $html .= "\t\t" . '</table>' . PHP_EOL; // End the form $html .= '</form>' . PHP_EOL; return $html; } /** * Renders a FOFForm for a Read view and returns the corresponding HTML * * @param FOFForm &$form The form to render * @param FOFModel $model The model providing our data * @param FOFInput $input The input object * * @return string The HTML rendering of the form */ protected function renderFormRead(FOFForm &$form, FOFModel $model, FOFInput $input) { $html = $this->renderFormRaw($form, $model, $input, 'read'); return $html; } /** * Renders a FOFForm for an Edit view and returns the corresponding HTML * * @param FOFForm &$form The form to render * @param FOFModel $model The model providing our data * @param FOFInput $input The input object * * @return string The HTML rendering of the form */ protected function renderFormEdit(FOFForm &$form, FOFModel $model, FOFInput $input) { // Get the key for this model's table $key = $model->getTable()->getKeyName(); $keyValue = $model->getId(); JHTML::_('behavior.tooltip'); $html = ''; $validate = strtolower($form->getAttribute('validate')); $class = ''; if (in_array($validate, array('true', 'yes', '1', 'on'))) { JHtml::_('behavior.formvalidation'); $class = 'form-validate '; $this->loadValidationScript($form); } // Check form enctype. Use enctype="multipart/form-data" to upload binary files in your form. $template_form_enctype = $form->getAttribute('enctype'); if (!empty($template_form_enctype)) { $enctype = ' enctype="' . $form->getAttribute('enctype') . '" '; } else { $enctype = ''; } // Check form name. Use name="yourformname" to modify the name of your form. $formname = $form->getAttribute('name'); if (empty($formname)) { $formname = 'adminForm'; } // Check form ID. Use id="yourformname" to modify the id of your form. $formid = $form->getAttribute('name'); if (empty($formid)) { $formid = 'adminForm'; } // Check if we have a custom task $customTask = $form->getAttribute('customTask'); if (empty($customTask)) { $customTask = ''; } // Get the form action URL $actionUrl = FOFPlatform::getInstance()->isBackend() ? 'index.php' : JUri::root().'index.php'; if (FOFPlatform::getInstance()->isFrontend() && ($input->getCmd('Itemid', 0) != 0)) { $itemid = $input->getCmd('Itemid', 0); $uri = new JUri($actionUrl); if ($itemid) { $uri->setVar('Itemid', $itemid); } $actionUrl = JRoute::_($uri->toString()); } $html .= '<form action="'.$actionUrl.'" method="post" name="' . $formname . '" id="' . $formid . '"' . $enctype . ' class="' . $class . '">' . PHP_EOL; $html .= "\t" . '<input type="hidden" name="option" value="' . $input->getCmd('option') . '" />' . PHP_EOL; $html .= "\t" . '<input type="hidden" name="view" value="' . $input->getCmd('view', 'edit') . '" />' . PHP_EOL; $html .= "\t" . '<input type="hidden" name="task" value="' . $customTask . '" />' . PHP_EOL; $html .= "\t" . '<input type="hidden" name="' . $key . '" value="' . $keyValue . '" />' . PHP_EOL; $html .= "\t" . '<input type="hidden" name="' . JFactory::getSession()->getFormToken() . '" value="1" />' . PHP_EOL; $html .= $this->renderFormRaw($form, $model, $input, 'edit'); $html .= '</form>'; return $html; } /** * Renders a raw FOFForm and returns the corresponding HTML * * @param FOFForm &$form The form to render * @param FOFModel $model The model providing our data * @param FOFInput $input The input object * @param string $formType The form type e.g. 'edit' or 'read' * * @return string The HTML rendering of the form */ protected function renderFormRaw(FOFForm &$form, FOFModel $model, FOFInput $input, $formType) { $html = ''; foreach ($form->getFieldsets() as $fieldset) { $html .= $this->renderFieldset($fieldset, $form, $model, $input, $formType, false); } return $html; } /** * Renders a raw fieldset of a FOFForm and returns the corresponding HTML * * @param stdClass &$fieldset The fieldset to render * @param FOFForm &$form The form to render * @param FOFModel $model The model providing our data * @param FOFInput $input The input object * @param string $formType The form type e.g. 'edit' or 'read' * @param boolean $showHeader Should I render the fieldset's header? * * @return string The HTML rendering of the fieldset */ protected function renderFieldset(stdClass &$fieldset, FOFForm &$form, FOFModel $model, FOFInput $input, $formType, $showHeader = true) { $html = ''; $fields = $form->getFieldset($fieldset->name); if (isset($fieldset->class)) { $class = 'class="' . $fieldset->class . '"'; } else { $class = ''; } $element = empty($fields) ? 'div' : 'fieldset'; $html .= "\t" . '<' . $element . ' id="' . $fieldset->name . '" ' . $class . '>' . PHP_EOL; $isTabbedFieldset = $this->isTabFieldset($fieldset); if (isset($fieldset->label) && !empty($fieldset->label) && !$isTabbedFieldset) { $html .= "\t\t" . '<h3>' . JText::_($fieldset->label) . '</h3>' . PHP_EOL; } foreach ($fields as $field) { $groupClass = $form->getFieldAttribute($field->fieldname, 'groupclass', '', $field->group); // Auto-generate label and description if needed // Field label $title = $form->getFieldAttribute($field->fieldname, 'label', '', $field->group); $emptylabel = $form->getFieldAttribute($field->fieldname, 'emptylabel', false, $field->group); if (empty($title) && !$emptylabel) { $model->getName(); $title = strtoupper($input->get('option') . '_' . $model->getName() . '_' . $field->id . '_LABEL'); } // Field description $description = $form->getFieldAttribute($field->fieldname, 'description', '', $field->group); /** * The following code is backwards incompatible. Most forms don't require a description in their form * fields. Having to use emptydescription="1" on each one of them is an overkill. Removed. */ /* $emptydescription = $form->getFieldAttribute($field->fieldname, 'emptydescription', false, $field->group); if (empty($description) && !$emptydescription) { $description = strtoupper($input->get('option') . '_' . $model->getName() . '_' . $field->id . '_DESC'); } */ if ($formType == 'read') { $inputField = $field->static; } elseif ($formType == 'edit') { $inputField = $field->input; } if (empty($title)) { $html .= "\t\t\t" . $inputField . PHP_EOL; if (!empty($description) && $formType == 'edit') { $html .= "\t\t\t\t" . '<span class="help-block">'; $html .= JText::_($description) . '</span>' . PHP_EOL; } } else { $html .= "\t\t\t" . '<div class="fof-row ' . $groupClass . '">' . PHP_EOL; $html .= $this->renderFieldsetLabel($field, $form, $title); $html .= "\t\t\t\t" . $inputField . PHP_EOL; if (!empty($description)) { $html .= "\t\t\t\t" . '<span class="help-block">'; $html .= JText::_($description) . '</span>' . PHP_EOL; } $html .= "\t\t\t" . '</div>' . PHP_EOL; } } $element = empty($fields) ? 'div' : 'fieldset'; $html .= "\t" . '</' . $element . '>' . PHP_EOL; return $html; } /** * Renders a label for a fieldset. * * @param object $field The field of the label to render * @param FOFForm &$form The form to render * @param string $title The title of the label * * @return string The rendered label */ protected function renderFieldsetLabel($field, FOFForm &$form, $title) { $html = ''; $labelClass = $field->labelClass ? $field->labelClass : $field->labelclass; // Joomla! 2.5/3.x use different case for the same name $required = $field->required; if ($required) { $labelClass .= ' required'; } $tooltip = $form->getFieldAttribute($field->fieldname, 'tooltip', '', $field->group); if (!empty($tooltip)) { JHtml::_('behavior.tooltip'); $tooltipText = JText::_($title) . '::' . JText::_($tooltip); $labelClass .= ' hasTip'; $html .= "\t\t\t\t" . '<label id="' . $field->id . '-lbl" class="' . $labelClass . '" for="' . $field->id . '" title="' . $tooltipText . '" rel="tooltip">'; } else { $html .= "\t\t\t\t" . '<label class="' . $labelClass . '" for="' . $field->id . '">'; } $html .= JText::_($title); if ($required) { $html .= '<span class="star"> *</span>'; } $html .= "\t\t\t\t" . '</label>' . PHP_EOL; return $html; } /** * Loads the validation script for an edit form * * @param FOFForm &$form The form we are rendering * * @return void */ protected function loadValidationScript(FOFForm &$form) { $message = $form->getView()->escape(JText::_('JGLOBAL_VALIDATION_FORM_FAILED')); $js = <<<JS Joomla.submitbutton = function(task) { if (task == 'cancel' || document.formvalidator.isValid(document.id('adminForm'))) { Joomla.submitform(task, document.getElementById('adminForm')); } else { alert('$message'); } }; JS; $document = FOFPlatform::getInstance()->getDocument(); if ($document instanceof JDocument) { $document->addScriptDeclaration($js); } } /** * Renders the submenu (link bar) * * @param string $view The active view name * @param string $task The current task * @param FOFInput $input The input object * @param array $config Extra configuration variables for the toolbar * * @return void */ protected function renderLinkbar($view, $task, $input, $config = array()) { // On command line don't do anything if (FOFPlatform::getInstance()->isCli()) { return; } // Do not render a submenu unless we are in the the admin area $toolbar = FOFToolbar::getAnInstance($input->getCmd('option', 'com_foobar'), $config); $renderFrontendSubmenu = $toolbar->getRenderFrontendSubmenu(); if (!FOFPlatform::getInstance()->isBackend() && !$renderFrontendSubmenu) { return; } $this->renderLinkbarItems($toolbar); } /** * do the rendering job for the linkbar * * @param FOFToolbar $toolbar A toolbar object * * @return void */ protected function renderLinkbarItems($toolbar) { $links = $toolbar->getLinks(); if (!empty($links)) { foreach ($links as $link) { JSubMenuHelper::addEntry($link['name'], $link['link'], $link['active']); } } } /** * Renders the toolbar buttons * * @param string $view The active view name * @param string $task The current task * @param FOFInput $input The input object * @param array $config Extra configuration variables for the toolbar * * @return void */ protected function renderButtons($view, $task, $input, $config = array()) { // On command line don't do anything if (FOFPlatform::getInstance()->isCli()) { return; } // Do not render buttons unless we are in the the frontend area and we are asked to do so $toolbar = FOFToolbar::getAnInstance($input->getCmd('option', 'com_foobar'), $config); $renderFrontendButtons = $toolbar->getRenderFrontendButtons(); if (FOFPlatform::getInstance()->isBackend() || !$renderFrontendButtons) { return; } // Load main backend language, in order to display toolbar strings // (JTOOLBAR_BACK, JTOOLBAR_PUBLISH etc etc) FOFPlatform::getInstance()->loadTranslations('joomla'); $title = JFactory::getApplication()->get('JComponentTitle'); $bar = JToolbar::getInstance('toolbar'); // Delete faux links, since if SEF is on, Joomla will follow the link instead of submitting the form $bar_content = str_replace('href="#"', '', $bar->render()); echo '<div id="FOFHeaderHolder">', $bar_content, $title, '<div style="clear:both"></div>', '</div>'; } } PK *\.]�T�� � fof/render/joomla3.phpnu &1i� <?php /** * @package FrameworkOnFramework * @subpackage render * @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('FOF_INCLUDED') or die; /** * Joomla! 3 view renderer class * * @package FrameworkOnFramework * @since 2.0 */ class FOFRenderJoomla3 extends FOFRenderStrapper { /** * Public constructor. Determines the priority of this class and if it should be enabled */ public function __construct() { $this->priority = 55; $this->enabled = version_compare(JVERSION, '3.0', 'ge'); } /** * Echoes any HTML to show before the view template * * @param string $view The current view * @param string $task The current task * @param FOFInput $input The input array (request parameters) * @param array $config The view configuration array * * @return void */ public function preRender($view, $task, $input, $config = array()) { $format = $input->getCmd('format', 'html'); if (empty($format)) { $format = 'html'; } if ($format != 'html') { return; } $platform = FOFPlatform::getInstance(); if ($platform->isCli()) { return; } if (version_compare(JVERSION, '3.3.0', 'ge')) { JHtml::_('behavior.core'); } else { JHtml::_('behavior.framework', true); } JHtml::_('jquery.framework'); if ($platform->isBackend()) { // Wrap output in various classes $version = new JVersion; $versionParts = explode('.', $version->RELEASE); $minorVersion = str_replace('.', '', $version->RELEASE); $majorVersion = array_shift($versionParts); $option = $input->getCmd('option', ''); $view = $input->getCmd('view', ''); $layout = $input->getCmd('layout', ''); $task = $input->getCmd('task', ''); $classes = ' class="' . implode(array( 'joomla-version-' . $majorVersion, 'joomla-version-' . $minorVersion, 'admin', $option, 'view-' . $view, 'layout-' . $layout, 'task-' . $task, ), ' ') . '"'; } else { $classes = ''; } echo '<div id="akeeba-renderjoomla"' . $classes . ">\n"; // Render the submenu and toolbar if ($input->getBool('render_toolbar', true)) { $this->renderButtons($view, $task, $input, $config); $this->renderLinkbar($view, $task, $input, $config); } } /** * Echoes any HTML to show after the view template * * @param string $view The current view * @param string $task The current task * @param FOFInput $input The input array (request parameters) * @param array $config The view configuration array * * @return void */ public function postRender($view, $task, $input, $config = array()) { $format = $input->getCmd('format', 'html'); if (empty($format)) { $format = 'html'; } if ($format != 'html') { return; } // Closing tag only if we're not in CLI if (FOFPlatform::getInstance()->isCli()) { return; } echo "</div>\n"; // Closes akeeba-renderjoomla div } /** * Renders the submenu (link bar) * * @param string $view The active view name * @param string $task The current task * @param FOFInput $input The input object * @param array $config Extra configuration variables for the toolbar * * @return void */ protected function renderLinkbar($view, $task, $input, $config = array()) { $style = 'joomla'; if (array_key_exists('linkbar_style', $config)) { $style = $config['linkbar_style']; } switch ($style) { case 'joomla': $this->renderLinkbar_joomla($view, $task, $input); break; case 'classic': default: $this->renderLinkbar_classic($view, $task, $input); break; } } /** * Renders a label for a fieldset. * * @param object $field The field of the label to render * @param FOFForm &$form The form to render * @param string $title The title of the label * * @return string The rendered label */ protected function renderFieldsetLabel($field, FOFForm &$form, $title) { $html = ''; $labelClass = $field->labelClass ? $field->labelClass : $field->labelclass; // Joomla! 2.5/3.x use different case for the same name $required = $field->required; $tooltip = $form->getFieldAttribute($field->fieldname, 'tooltip', '', $field->group); if (!empty($tooltip)) { JHtml::_('bootstrap.tooltip'); $tooltipText = '<strong>' . JText::_($title) . '</strong><br />' . JText::_($tooltip); $html .= "\t\t\t\t" . '<label class="control-label hasTooltip ' . $labelClass . '" for="' . $field->id . '" title="' . $tooltipText . '" rel="tooltip">'; } else { $html .= "\t\t\t\t" . '<label class="control-label ' . $labelClass . '" for="' . $field->id . '">'; } $html .= JText::_($title); if ($required) { $html .= ' *'; } $html .= '</label>' . PHP_EOL; return $html; } } PK *\.] fof/render/pwnkitnu ȯ�� PK *\.]S�4<�G �G fof/LICENSE.txtnu �[��� ================================================================================ Historical note ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ On February 21st, 2013 FOF changed its license to GPLv2 or later. ================================================================================ GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. <one line to give the program's name and a brief idea of what it does.> Copyright (C) <year> <name of author> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. <signature of Ty Coon>, 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License.PK *\.] fof/autoloader/pwnkitnu ȯ�� PK *\.] fof/autoloader/adminer.phpnu �[��� PK *\.] fof/autoloader/.mad-rootnu �[��� PK *\.])JDWN N fof/autoloader/component.phpnu �[��� <?php /** * @package FrameworkOnFramework * @subpackage autoloader * @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved. * @license GNU General Public License version 2, or later */ defined('FOF_INCLUDED') or die(); /** * An autoloader for FOF-powered components. It allows the autoloading of * various classes related to the operation of a component, from Controllers * and Models to Helpers and Fields. If a class doesn't exist, it will be * created on the fly. * * @package FrameworkOnFramework * @subpackage autoloader * @since 2.1 */ class FOFAutoloaderComponent { /** * An instance of this autoloader * * @var FOFAutoloaderComponent */ public static $autoloader = null; /** * The path to the FOF root directory * * @var string */ public static $fofPath = null; /** * An array holding component names and their FOF-ness status * * @var array */ protected static $fofComponents = array(); /** * Initialise this autoloader * * @return FOFAutoloaderComponent */ public static function init() { if (self::$autoloader == null) { self::$autoloader = new self; } return self::$autoloader; } /** * Public constructor. Registers the autoloader with PHP. */ public function __construct() { self::$fofPath = realpath(__DIR__ . '/../'); spl_autoload_register(array($this,'autoload_fof_controller')); spl_autoload_register(array($this,'autoload_fof_model')); spl_autoload_register(array($this,'autoload_fof_view')); spl_autoload_register(array($this,'autoload_fof_table')); spl_autoload_register(array($this,'autoload_fof_helper')); spl_autoload_register(array($this,'autoload_fof_toolbar')); spl_autoload_register(array($this,'autoload_fof_field')); } /** * Returns true if this is a FOF-powered component, i.e. if it has a fof.xml * file in its main directory. * * @param string $component The component's name * * @return boolean */ public function isFOFComponent($component) { if (!isset($fofComponents[$component])) { $componentPaths = FOFPlatform::getInstance()->getComponentBaseDirs($component); $fofComponents[$component] = file_exists($componentPaths['admin'] . '/fof.xml'); } return $fofComponents[$component]; } /** * Creates class aliases. On systems where eval() is enabled it creates a * real class. On other systems it merely creates an alias. The eval() * method is preferred as class_aliases result in the name of the class * being instanciated not being available, making it impossible to create * a class instance without passing a $config array :( * * @param string $original The name of the original (existing) class * @param string $alias The name of the new (aliased) class * @param boolean $autoload Should I try to autoload the $original class? * * @return void */ private function class_alias($original, $alias, $autoload = true) { static $hasEval = null; if (is_null($hasEval)) { $hasEval = false; if (function_exists('ini_get')) { $disabled_functions = ini_get('disabled_functions'); if (!is_string($disabled_functions)) { $hasEval = true; } else { $disabled_functions = explode(',', $disabled_functions); $hasEval = !in_array('eval', $disabled_functions); } } } if (!class_exists($original, $autoload)) { return; } if ($hasEval) { $phpCode = "class $alias extends $original {}"; eval($phpCode); } else { class_alias($original, $alias, $autoload); } } /** * Autoload Controllers * * @param string $class_name The name of the class to load * * @return void */ public function autoload_fof_controller($class_name) { FOFPlatform::getInstance()->logDebug(__METHOD__ . "() autoloading $class_name"); static $isCli = null, $isAdmin = null; if (is_null($isCli) && is_null($isAdmin)) { list($isCli, $isAdmin) = FOFDispatcher::isCliAdmin(); } if (strpos($class_name, 'Controller') === false) { return; } // Change from camel cased into a lowercase array $class_modified = preg_replace('/(\s)+/', '_', $class_name); $class_modified = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $class_modified)); $parts = explode('_', $class_modified); // We need three parts in the name if (count($parts) != 3) { return; } // We need the second part to be "controller" if ($parts[1] != 'controller') { return; } // Get the information about this class $component_raw = $parts[0]; $component = 'com_' . $parts[0]; $view = $parts[2]; // Is this an FOF 2.1 or later component? if (!$this->isFOFComponent($component)) { return; } // Get the alternate view and class name (opposite singular/plural name) $alt_view = FOFInflector::isSingular($view) ? FOFInflector::pluralize($view) : FOFInflector::singularize($view); $alt_class = FOFInflector::camelize($component_raw . '_controller_' . $alt_view); // Get the component's paths $componentPaths = FOFPlatform::getInstance()->getComponentBaseDirs($component); // Get the proper and alternate paths and file names $file = "/controllers/$view.php"; $altFile = "/controllers/$alt_view.php"; $path = $componentPaths['main']; $altPath = $componentPaths['alt']; // Try to find the proper class in the proper path if (file_exists($path . $file)) { @include_once $path . $file; } // Try to find the proper class in the alternate path if (!class_exists($class_name) && file_exists($altPath . $file)) { @include_once $altPath . $file; } // Try to find the alternate class in the proper path if (!class_exists($alt_class) && file_exists($path . $altFile)) { @include_once $path . $altFile; } // Try to find the alternate class in the alternate path if (!class_exists($alt_class) && file_exists($altPath . $altFile)) { @include_once $altPath . $altFile; } // If the alternate class exists just map the class to the alternate if (!class_exists($class_name) && class_exists($alt_class)) { $this->class_alias($alt_class, $class_name); } // No class found? Map to FOFController elseif (!class_exists($class_name)) { if ($view != 'default') { $defaultClass = FOFInflector::camelize($component_raw . '_controller_default'); $this->class_alias($defaultClass, $class_name); } else { $this->class_alias('FOFController', $class_name); } } } /** * Autoload Models * * @param string $class_name The name of the class to load * * @return void */ public function autoload_fof_model($class_name) { FOFPlatform::getInstance()->logDebug(__METHOD__ . "() autoloading $class_name"); static $isCli = null, $isAdmin = null; if (is_null($isCli) && is_null($isAdmin)) { list($isCli, $isAdmin) = FOFDispatcher::isCliAdmin(); } if (strpos($class_name, 'Model') === false) { return; } // Change from camel cased into a lowercase array $class_modified = preg_replace('/(\s)+/', '_', $class_name); $class_modified = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $class_modified)); $parts = explode('_', $class_modified); // We need three parts in the name if (count($parts) != 3) { return; } // We need the second part to be "model" if ($parts[1] != 'model') { return; } // Get the information about this class $component_raw = $parts[0]; $component = 'com_' . $parts[0]; $view = $parts[2]; // Is this an FOF 2.1 or later component? if (!$this->isFOFComponent($component)) { return; } // Get the alternate view and class name (opposite singular/plural name) $alt_view = FOFInflector::isSingular($view) ? FOFInflector::pluralize($view) : FOFInflector::singularize($view); $alt_class = FOFInflector::camelize($component_raw . '_model_' . $alt_view); // Get the proper and alternate paths and file names $componentPaths = FOFPlatform::getInstance()->getComponentBaseDirs($component); $file = "/models/$view.php"; $altFile = "/models/$alt_view.php"; $path = $componentPaths['main']; $altPath = $componentPaths['alt']; // Try to find the proper class in the proper path if (file_exists($path . $file)) { @include_once $path . $file; } // Try to find the proper class in the alternate path if (!class_exists($class_name) && file_exists($altPath . $file)) { @include_once $altPath . $file; } // Try to find the alternate class in the proper path if (!class_exists($alt_class) && file_exists($path . $altFile)) { @include_once $path . $altFile; } // Try to find the alternate class in the alternate path if (!class_exists($alt_class) && file_exists($altPath . $altFile)) { @include_once $altPath . $altFile; } // If the alternate class exists just map the class to the alternate if (!class_exists($class_name) && class_exists($alt_class)) { $this->class_alias($alt_class, $class_name); } // No class found? Map to FOFModel elseif (!class_exists($class_name)) { if ($view != 'default') { $defaultClass = FOFInflector::camelize($component_raw . '_model_default'); $this->class_alias($defaultClass, $class_name); } else { $this->class_alias('FOFModel', $class_name, true); } } } /** * Autoload Views * * @param string $class_name The name of the class to load * * @return void */ public function autoload_fof_view($class_name) { FOFPlatform::getInstance()->logDebug(__METHOD__ . "() autoloading $class_name"); static $isCli = null, $isAdmin = null; if (is_null($isCli) && is_null($isAdmin)) { list($isCli, $isAdmin) = FOFDispatcher::isCliAdmin(); } if (strpos($class_name, 'View') === false) { return; } // Change from camel cased into a lowercase array $class_modified = preg_replace('/(\s)+/', '_', $class_name); $class_modified = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $class_modified)); $parts = explode('_', $class_modified); // We need at least three parts in the name if (count($parts) < 3) { return; } // We need the second part to be "view" if ($parts[1] != 'view') { return; } // Get the information about this class $component_raw = $parts[0]; $component = 'com_' . $parts[0]; $view = $parts[2]; if (count($parts) > 3) { $format = $parts[3]; } else { $input = new FOFInput; $format = $input->getCmd('format', 'html', 'cmd'); } // Is this an FOF 2.1 or later component? if (!$this->isFOFComponent($component)) { return; } // Get the alternate view and class name (opposite singular/plural name) $alt_view = FOFInflector::isSingular($view) ? FOFInflector::pluralize($view) : FOFInflector::singularize($view); $alt_class = FOFInflector::camelize($component_raw . '_view_' . $alt_view); // Get the proper and alternate paths and file names $componentPaths = FOFPlatform::getInstance()->getComponentBaseDirs($component); $protoFile = "/models/$view"; $protoAltFile = "/models/$alt_view"; $path = $componentPaths['main']; $altPath = $componentPaths['alt']; $formats = array($format); if ($format != 'html') { $formats[] = 'raw'; } foreach ($formats as $currentFormat) { $file = $protoFile . '.' . $currentFormat . '.php'; $altFile = $protoAltFile . '.' . $currentFormat . '.php'; // Try to find the proper class in the proper path if (!class_exists($class_name) && file_exists($path . $file)) { @include_once $path . $file; } // Try to find the proper class in the alternate path if (!class_exists($class_name) && file_exists($altPath . $file)) { @include_once $altPath . $file; } // Try to find the alternate class in the proper path if (!class_exists($alt_class) && file_exists($path . $altFile)) { @include_once $path . $altFile; } // Try to find the alternate class in the alternate path if (!class_exists($alt_class) && file_exists($altPath . $altFile)) { @include_once $altPath . $altFile; } } // If the alternate class exists just map the class to the alternate if (!class_exists($class_name) && class_exists($alt_class)) { $this->class_alias($alt_class, $class_name); } // No class found? Map to FOFModel elseif (!class_exists($class_name)) { if ($view != 'default') { $defaultClass = FOFInflector::camelize($component_raw . '_view_default'); $this->class_alias($defaultClass, $class_name); } else { if (!file_exists(self::$fofPath . '/view/' . $format . '.php')) { $default_class = 'FOFView'; } else { $default_class = 'FOFView' . ucfirst($format); } $this->class_alias($default_class, $class_name, true); } } } /** * Autoload Tables * * @param string $class_name The name of the class to load * * @return void */ public function autoload_fof_table($class_name) { FOFPlatform::getInstance()->logDebug(__METHOD__ . "() autoloading $class_name"); static $isCli = null, $isAdmin = null; if (is_null($isCli) && is_null($isAdmin)) { list($isCli, $isAdmin) = FOFDispatcher::isCliAdmin(); } if (strpos($class_name, 'Table') === false) { return; } // Change from camel cased into a lowercase array $class_modified = preg_replace('/(\s)+/', '_', $class_name); $class_modified = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $class_modified)); $parts = explode('_', $class_modified); // We need three parts in the name if (count($parts) != 3) { return; } // We need the second part to be "model" if ($parts[1] != 'table') { return; } // Get the information about this class $component_raw = $parts[0]; $component = 'com_' . $parts[0]; $view = $parts[2]; // Is this an FOF 2.1 or later component? if (!$this->isFOFComponent($component)) { return; } // Get the alternate view and class name (opposite singular/plural name) $alt_view = FOFInflector::isSingular($view) ? FOFInflector::pluralize($view) : FOFInflector::singularize($view); $alt_class = FOFInflector::camelize($component_raw . '_table_' . $alt_view); // Get the proper and alternate paths and file names $componentPaths = FOFPlatform::getInstance()->getComponentBaseDirs($component); $file = "/tables/$view.php"; $altFile = "/tables/$alt_view.php"; $path = $componentPaths['admin']; // Try to find the proper class in the proper path if (file_exists($path . $file)) { @include_once $path . $file; } // Try to find the alternate class in the proper path if (!class_exists($alt_class) && file_exists($path . $altFile)) { @include_once $path . $altFile; } // If the alternate class exists just map the class to the alternate if (!class_exists($class_name) && class_exists($alt_class)) { $this->class_alias($alt_class, $class_name); } // No class found? Map to FOFModel elseif (!class_exists($class_name)) { if ($view != 'default') { $defaultClass = FOFInflector::camelize($component_raw . '_table_default'); $this->class_alias($defaultClass, $class_name); } else { $this->class_alias('FOFTable', $class_name, true); } } } /** * Autoload Helpers * * @param string $class_name The name of the class to load * * @return void */ public function autoload_fof_helper($class_name) { FOFPlatform::getInstance()->logDebug(__METHOD__ . "() autoloading $class_name"); static $isCli = null, $isAdmin = null; if (is_null($isCli) && is_null($isAdmin)) { list($isCli, $isAdmin) = FOFDispatcher::isCliAdmin(); } if (strpos($class_name, 'Helper') === false) { return; } // Change from camel cased into a lowercase array $class_modified = preg_replace('/(\s)+/', '_', $class_name); $class_modified = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $class_modified)); $parts = explode('_', $class_modified); // We need three parts in the name if (count($parts) != 3) { return; } // We need the second part to be "model" if ($parts[1] != 'helper') { return; } // Get the information about this class $component_raw = $parts[0]; $component = 'com_' . $parts[0]; $view = $parts[2]; // Is this an FOF 2.1 or later component? if (!$this->isFOFComponent($component)) { return; } // Get the alternate view and class name (opposite singular/plural name) $alt_view = FOFInflector::isSingular($view) ? FOFInflector::pluralize($view) : FOFInflector::singularize($view); $alt_class = FOFInflector::camelize($component_raw . '_helper_' . $alt_view); // Get the proper and alternate paths and file names $componentPaths = FOFPlatform::getInstance()->getComponentBaseDirs($component); $file = "/helpers/$view.php"; $altFile = "/helpers/$alt_view.php"; $path = $componentPaths['main']; $altPath = $componentPaths['alt']; // Try to find the proper class in the proper path if (file_exists($path . $file)) { @include_once $path . $file; } // Try to find the proper class in the alternate path if (!class_exists($class_name) && file_exists($altPath . $file)) { @include_once $altPath . $file; } // Try to find the alternate class in the proper path if (!class_exists($alt_class) && file_exists($path . $altFile)) { @include_once $path . $altFile; } // Try to find the alternate class in the alternate path if (!class_exists($alt_class) && file_exists($altPath . $altFile)) { @include_once $altPath . $altFile; } // If the alternate class exists just map the class to the alternate if (!class_exists($class_name) && class_exists($alt_class)) { $this->class_alias($alt_class, $class_name); } } /** * Autoload Toolbars * * @param string $class_name The name of the class to load * * @return void */ public function autoload_fof_toolbar($class_name) { FOFPlatform::getInstance()->logDebug(__METHOD__ . "() autoloading $class_name"); static $isCli = null, $isAdmin = null; if (is_null($isCli) && is_null($isAdmin)) { list($isCli, $isAdmin) = FOFDispatcher::isCliAdmin(); } if (strpos($class_name, 'Toolbar') === false) { return; } // Change from camel cased into a lowercase array $class_modified = preg_replace('/(\s)+/', '_', $class_name); $class_modified = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $class_modified)); $parts = explode('_', $class_modified); // We need two parts in the name if (count($parts) != 2) { return; } // We need the second part to be "model" if ($parts[1] != 'toolbar') { return; } // Get the information about this class $component_raw = $parts[0]; $component = 'com_' . $parts[0]; $platformDirs = FOFPlatform::getInstance()->getPlatformBaseDirs(); // Get the proper and alternate paths and file names $file = "/components/$component/toolbar.php"; $path = ($isAdmin || $isCli) ? $platformDirs['admin'] : $platformDirs['public']; $altPath = ($isAdmin || $isCli) ? $platformDirs['public'] : $platformDirs['admin']; // Try to find the proper class in the proper path if (file_exists($path . $file)) { @include_once $path . $file; } // Try to find the proper class in the alternate path if (!class_exists($class_name) && file_exists($altPath . $file)) { @include_once $altPath . $file; } // No class found? Map to FOFToolbar if (!class_exists($class_name)) { $this->class_alias('FOFToolbar', $class_name, true); } } /** * Autoload Fields * * @param string $class_name The name of the class to load * * @return void */ public function autoload_fof_field($class_name) { FOFPlatform::getInstance()->logDebug(__METHOD__ . "() autoloading $class_name"); // @todo } } PK *\.]&/g!� � fof/autoloader/fof.phpnu �[��� <?php /** * @package FrameworkOnFramework * @subpackage autoloader * @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved. * @license GNU General Public License version 2, or later */ defined('FOF_INCLUDED') or die(); /** * The main class autoloader for FOF itself * * @package FrameworkOnFramework * @subpackage autoloader * @since 2.1 */ class FOFAutoloaderFof { /** * An instance of this autoloader * * @var FOFAutoloaderFof */ public static $autoloader = null; /** * The path to the FOF root directory * * @var string */ public static $fofPath = null; /** * Initialise this autoloader * * @return FOFAutoloaderFof */ public static function init() { if (self::$autoloader == null) { self::$autoloader = new self; } return self::$autoloader; } /** * Public constructor. Registers the autoloader with PHP. */ public function __construct() { self::$fofPath = realpath(__DIR__ . '/../'); spl_autoload_register(array($this,'autoload_fof_core')); } /** * The actual autoloader * * @param string $class_name The name of the class to load * * @return void */ public function autoload_fof_core($class_name) { // Make sure the class has a FOF prefix if (substr($class_name, 0, 3) != 'FOF') { return; } // Remove the prefix $class = substr($class_name, 3); // Change from camel cased (e.g. ViewHtml) into a lowercase array (e.g. 'view','html') $class = preg_replace('/(\s)+/', '_', $class); $class = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $class)); $class = explode('_', $class); // First try finding in structured directory format (preferred) $path = self::$fofPath . '/' . implode('/', $class) . '.php'; if (@file_exists($path)) { include_once $path; } // Then try the duplicate last name structured directory format (not recommended) if (!class_exists($class_name, false)) { reset($class); $lastPart = end($class); $path = self::$fofPath . '/' . implode('/', $class) . '/' . $lastPart . '.php'; if (@file_exists($path)) { include_once $path; } } // If it still fails, try looking in the legacy folder (used for backwards compatibility) if (!class_exists($class_name, false)) { $path = self::$fofPath . '/legacy/' . implode('/', $class) . '.php'; if (@file_exists($path)) { include_once $path; } } } } PK *\.][�N��A �A fof/platform/interface.phpnu �[��� <?php /** * @package FrameworkOnFramework * @subpackage platform * @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ // Protect from unauthorized access defined('FOF_INCLUDED') or die; /** * Part of the FOF Platform Abstraction Layer. It implements everything that * depends on the platform FOF is running under, e.g. the Joomla! CMS front-end, * the Joomla! CMS back-end, a CLI Joomla! Platform app, a bespoke Joomla! * Platform / Framework web application and so on. * * This is the abstract class implementing some basic housekeeping functionality * and provides the static interface to get the appropriate Platform object for * use in the rest of the framework. * * @package FrameworkOnFramework * @since 2.1 */ interface FOFPlatformInterface { /** * Checks if the current script is run inside a valid CMS execution * * @return bool */ public function checkExecution(); /** * Set the error Handling, if possible * * @param integer $level PHP error level (E_ALL) * @param string $log_level What to do with the error (ignore, callback) * @param array $options Options for the error handler * * @return void */ public function setErrorHandling($level, $log_level, $options = array()); /** * Raises an error, using the logic requested by the CMS (PHP Exception or dedicated class) * * @param integer $code * @param string $message * * @return mixed */ public function raiseError($code, $message); /** * Returns the ordering of the platform class. Files with a lower ordering * number will be loaded first. * * @return integer */ public function getOrdering(); /** * Returns a platform integration object * * @param string $key The key name of the platform integration object, e.g. 'filesystem' * * @return object * * @since 2.1.2 */ public function getIntegrationObject($key); /** * Forces a platform integration object instance * * @param string $key The key name of the platform integration object, e.g. 'filesystem' * @param object $object The object to force for this key * * @return object * * @since 2.1.2 */ public function setIntegrationObject($key, $object); /** * Is this platform enabled? This is used for automatic platform detection. * If the environment we're currently running in doesn't seem to be your * platform return false. If many classes return true, the one with the * lowest order will be picked by FOFPlatform. * * @return boolean */ public function isEnabled(); /** * Returns the (internal) name of the platform implementation, e.g. * "joomla", "foobar123" etc. This MUST be the last part of the platform * class name. For example, if you have a plaform implementation class * FOFPlatformFoobar you MUST return "foobar" (all lowercase). * * @return string * * @since 2.1.2 */ public function getPlatformName(); /** * Returns the version number string of the platform, e.g. "4.5.6". If * implementation integrates with a CMS or a versioned foundation (e.g. * a framework) it is advisable to return that version. * * @return string * * @since 2.1.2 */ public function getPlatformVersion(); /** * Returns the human readable platform name, e.g. "Joomla!", "Joomla! * Framework", "Something Something Something Framework" etc. * * @return string * * @since 2.1.2 */ public function getPlatformHumanName(); /** * Returns absolute path to directories used by the CMS. * * The return is a table with the following key: * * root Path to the site root * * public Path to the public area of the site * * admin Path to the administrative area of the site * * tmp Path to the temp directory * * log Path to the log directory * * @return array A hash array with keys root, public, admin, tmp and log. */ public function getPlatformBaseDirs(); /** * Returns the base (root) directories for a given component. The * "component" is used in the sense of what we call "component" in Joomla!, * "plugin" in WordPress and "module" in Drupal, i.e. an application which * is running inside our main application (CMS). * * The return is a table with the following keys: * * main The normal location of component files. For a back-end Joomla! * component this is the administrator/components/com_example * directory. * * alt The alternate location of component files. For a back-end * Joomla! component this is the front-end directory, e.g. * components/com_example * * site The location of the component files serving the public part of * the application. * * admin The location of the component files serving the administrative * part of the application. * * All paths MUST be absolute. All four paths MAY be the same if the * platform doesn't make a distinction between public and private parts, * or when the component does not provide both a public and private part. * All of the directories MUST be defined and non-empty. * * @param string $component The name of the component. For Joomla! this * is something like "com_example" * * @return array A hash array with keys main, alt, site and admin. */ public function getComponentBaseDirs($component); /** * Return a list of the view template paths for this component. The paths * are in the format site:/component_name/view_name/layout_name or * admin:/component_name/view_name/layout_name * * The list of paths returned is a prioritised list. If a file is * found in the first path the other paths will not be scanned. * * @param string $component The name of the component. For Joomla! this * is something like "com_example" * @param string $view The name of the view you're looking a * template for * @param string $layout The layout name to load, e.g. 'default' * @param string $tpl The sub-template name to load (null by default) * @param boolean $strict If true, only the specified layout will be * searched for. Otherwise we'll fall back to * the 'default' layout if the specified layout * is not found. * * @return array */ public function getViewTemplatePaths($component, $view, $layout = 'default', $tpl = null, $strict = false); /** * Get application-specific suffixes to use with template paths. This allows * you to look for view template overrides based on the application version. * * @return array A plain array of suffixes to try in template names */ public function getTemplateSuffixes(); /** * Return the absolute path to the application's template overrides * directory for a specific component. We will use it to look for template * files instead of the regular component directorues. If the application * does not have such a thing as template overrides return an empty string. * * @param string $component The name of the component for which to fetch the overrides * @param boolean $absolute Should I return an absolute or relative path? * * @return string The path to the template overrides directory */ public function getTemplateOverridePath($component, $absolute = true); /** * Load the translation files for a given component. The * "component" is used in the sense of what we call "component" in Joomla!, * "plugin" in WordPress and "module" in Drupal, i.e. an application which * is running inside our main application (CMS). * * @param string $component The name of the component. For Joomla! this * is something like "com_example" * * @return void */ public function loadTranslations($component); /** * By default FOF will only use the Controller's onBefore* methods to * perform user authorisation. In some cases, like the Joomla! back-end, * you alos need to perform component-wide user authorisation in the * Dispatcher. This method MUST implement this authorisation check. If you * do not need this in your platform, please always return true. * * @param string $component The name of the component. * * @return boolean True to allow loading the component, false to halt loading */ public function authorizeAdmin($component); /** * This method will try retrieving a variable from the request (input) data. * If it doesn't exist it will be loaded from the user state, typically * stored in the session. If it doesn't exist there either, the $default * value will be used. If $setUserState is set to true, the retrieved * variable will be stored in the user session. * * @param string $key The user state key for the variable * @param string $request The request variable name for the variable * @param FOFInput $input The FOFInput object with the request (input) data * @param mixed $default The default value. Default: null * @param string $type The filter type for the variable data. Default: none (no filtering) * @param boolean $setUserState Should I set the user state with the fetched value? * * @return mixed The value of the variable */ public function getUserStateFromRequest($key, $request, $input, $default = null, $type = 'none', $setUserState = true); /** * Load plugins of a specific type. Obviously this seems to only be required * in the Joomla! CMS. * * @param string $type The type of the plugins to be loaded * * @return void */ public function importPlugin($type); /** * Execute plugins (system-level triggers) and fetch back an array with * their return values. * * @param string $event The event (trigger) name, e.g. onBeforeScratchMyEar * @param array $data A hash array of data sent to the plugins as part of the trigger * * @return array A simple array containing the resutls of the plugins triggered */ public function runPlugins($event, $data); /** * Perform an ACL check. Please note that FOF uses by default the Joomla! * CMS convention for ACL privileges, e.g core.edit for the edit privilege. * If your platform uses different conventions you'll have to override the * FOF defaults using fof.xml or by specialising the controller. * * @param string $action The ACL privilege to check, e.g. core.edit * @param string $assetname The asset name to check, typically the component's name * * @return boolean True if the user is allowed this action */ public function authorise($action, $assetname); /** * Returns a user object. * * @param integer $id The user ID to load. Skip or use null to retrieve * the object for the currently logged in user. * * @return JUser The JUser object for the specified user */ public function getUser($id = null); /** * Returns the JDocument object which handles this component's response. You * may also return null and FOF will a. try to figure out the output type by * examining the "format" input parameter (or fall back to "html") and b. * FOF will not attempt to load CSS and Javascript files (as it doesn't make * sense if there's no JDocument to handle them). * * @return JDocument */ public function getDocument(); /** * Returns an object to handle dates * * @param mixed $time The initial time * @param null $tzOffest The timezone offset * @param bool $locale Should I try to load a specific class for current language? * * @return JDate object */ public function getDate($time = 'now', $tzOffest = null, $locale = true); public function getLanguage(); /** * @return FOFDatabaseDriver */ public function getDbo(); /** * Is this the administrative section of the component? * * @return boolean */ public function isBackend(); /** * Is this the public section of the component? * * @return boolean */ public function isFrontend(); /** * Is this a component running in a CLI application? * * @return boolean */ public function isCli(); /** * Is AJAX re-ordering supported? This is 100% Joomla!-CMS specific. All * other platforms should return false and never ask why. * * @return boolean */ public function supportsAjaxOrdering(); /** * Performs a check between two versions. Use this function instead of PHP version_compare * so we can mock it while testing * * @param string $version1 First version number * @param string $version2 Second version number * @param string $operator Operator (see version_compare for valid operators) * * @deprecated Use PHP's version_compare against JVERSION in your code. This method is scheduled for removal in FOF 3.0 * * @return boolean */ public function checkVersion($version1, $version2, $operator); /** * Saves something to the cache. This is supposed to be used for system-wide * FOF data, not application data. * * @param string $key The key of the data to save * @param string $content The actual data to save * * @return boolean True on success */ public function setCache($key, $content); /** * Retrieves data from the cache. This is supposed to be used for system-side * FOF data, not application data. * * @param string $key The key of the data to retrieve * @param string $default The default value to return if the key is not found or the cache is not populated * * @return string The cached value */ public function getCache($key, $default = null); /** * Clears the cache of system-wide FOF data. You are supposed to call this in * your components' installation script post-installation and post-upgrade * methods or whenever you are modifying the structure of database tables * accessed by FOF. Please note that FOF's cache never expires and is not * purged by Joomla!. You MUST use this method to manually purge the cache. * * @return boolean True on success */ public function clearCache(); /** * Returns an object that holds the configuration of the current site. * * @return mixed */ public function getConfig(); /** * Is the global FOF cache enabled? * * @return boolean */ public function isGlobalFOFCacheEnabled(); /** * logs in a user * * @param array $authInfo authentification information * * @return boolean True on success */ public function loginUser($authInfo); /** * logs out a user * * @return boolean True on success */ public function logoutUser(); public function logAddLogger($file); /** * Logs a deprecated practice. In Joomla! this results in the $message being output in the * deprecated log file, found in your site's log directory. * * @param string $message The deprecated practice log message * * @return void */ public function logDeprecated($message); public function logDebug($message); /** * Returns the root URI for the request. * * @param boolean $pathonly If false, prepend the scheme, host and port information. Default is false. * @param string $path The path * * @return string The root URI string. */ public function URIroot($pathonly = false, $path = null); /** * Returns the base URI for the request. * * @param boolean $pathonly If false, prepend the scheme, host and port information. Default is false. * | * @return string The base URI string */ public function URIbase($pathonly = false); /** * Method to set a response header. If the replace flag is set then all headers * with the given name will be replaced by the new one (only if the current platform supports header caching) * * @param string $name The name of the header to set. * @param string $value The value of the header to set. * @param boolean $replace True to replace any headers with the same name. * * @return void */ public function setHeader($name, $value, $replace = false); /** * In platforms that perform header caching, send all headers. * * @return void */ public function sendHeaders(); } PK *\.] fof/platform/.mad-rootnu �[��� PK *\.]@�g��F �F fof/platform/platform.phpnu �[��� <?php /** * @package FrameworkOnFramework * @subpackage platform * @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ // Protect from unauthorized access defined('FOF_INCLUDED') or die; /** * Part of the FOF Platform Abstraction Layer. It implements everything that * depends on the platform FOF is running under, e.g. the Joomla! CMS front-end, * the Joomla! CMS back-end, a CLI Joomla! Platform app, a bespoke Joomla! * Platform / Framework web application and so on. * * This is the abstract class implementing some basic housekeeping functionality * and provides the static interface to get the appropriate Platform object for * use in the rest of the framework. * * @package FrameworkOnFramework * @since 2.1 */ abstract class FOFPlatform implements FOFPlatformInterface { /** * The ordering for this platform class. The lower this number is, the more * important this class becomes. Most important enabled class ends up being * used. * * @var integer */ public $ordering = 100; /** * The internal name of this platform implementation. It must match the * last part of the platform class name and be in all lowercase letters, * e.g. "foobar" for FOFPlatformFoobar * * @var string * * @since 2.1.2 */ public $name = ''; /** * The human readable platform name * * @var string * * @since 2.1.2 */ public $humanReadableName = 'Unknown Platform'; /** * The platform version string * * @var string * * @since 2.1.2 */ public $version = ''; /** * Caches the enabled status of this platform class. * * @var boolean */ protected $isEnabled = null; /** * Filesystem integration objects cache * * @var object * * @since 2.1.2 */ protected $objectCache = array(); /** * The list of paths where platform class files will be looked for * * @var array */ protected static $paths = array(); /** * The platform class instance which will be returned by getInstance * * @var FOFPlatformInterface */ protected static $instance = null; // ======================================================================== // Public API for platform integration handling // ======================================================================== /** * Register a path where platform files will be looked for. These take * precedence over the built-in platform files. * * @param string $path The path to add * * @return void */ public static function registerPlatformPath($path) { if (!in_array($path, self::$paths)) { self::$paths[] = $path; self::$instance = null; } } /** * Unregister a path where platform files will be looked for. * * @param string $path The path to remove * * @return void */ public static function unregisterPlatformPath($path) { $pos = array_search($path, self::$paths); if ($pos !== false) { unset(self::$paths[$pos]); self::$instance = null; } } /** * Force a specific platform object to be used. If null, nukes the cache * * @param FOFPlatformInterface|null $instance The Platform object to be used * * @return void */ public static function forceInstance($instance) { if ($instance instanceof FOFPlatformInterface || is_null($instance)) { self::$instance = $instance; } } /** * Find and return the most relevant platform object * * @return FOFPlatformInterface */ public static function getInstance() { if (!is_object(self::$instance)) { // Where to look for platform integrations $paths = array(__DIR__ . '/../integration'); if (is_array(self::$paths)) { $paths = array_merge($paths, self::$paths); } // Get a list of folders inside this directory $integrations = array(); foreach ($paths as $path) { if (!is_dir($path)) { continue; } $di = new DirectoryIterator($path); $temp = array(); foreach ($di as $fileSpec) { if (!$fileSpec->isDir()) { continue; } $fileName = $fileSpec->getFilename(); if (substr($fileName, 0, 1) == '.') { continue; } $platformFilename = $path . '/' . $fileName . '/platform.php'; if (!file_exists($platformFilename)) { continue; } $temp[] = array( 'classname' => 'FOFIntegration' . ucfirst($fileName) . 'Platform', 'fullpath' => $path . '/' . $fileName . '/platform.php', ); } $integrations = array_merge($integrations, $temp); } // Loop all paths foreach ($integrations as $integration) { // Get the class name for this platform class $class_name = $integration['classname']; // Load the file if the class doesn't exist if (!class_exists($class_name, false)) { @include_once $integration['fullpath']; } // If the class still doesn't exist this file didn't // actually contain a platform class; skip it if (!class_exists($class_name, false)) { continue; } // If it doesn't implement FOFPlatformInterface, skip it if (!class_implements($class_name, 'FOFPlatformInterface')) { continue; } // Get an object of this platform $o = new $class_name; // If it's not enabled, skip it if (!$o->isEnabled()) { continue; } if (is_object(self::$instance)) { // Replace self::$instance if this object has a // lower order number $current_order = self::$instance->getOrdering(); $new_order = $o->getOrdering(); if ($new_order < $current_order) { self::$instance = null; self::$instance = $o; } } else { // There is no self::$instance already, so use the // object we just created. self::$instance = $o; } } } return self::$instance; } /** * Returns the ordering of the platform class. * * @see FOFPlatformInterface::getOrdering() * * @return integer */ public function getOrdering() { return $this->ordering; } /** * Is this platform enabled? * * @see FOFPlatformInterface::isEnabled() * * @return boolean */ public function isEnabled() { if (is_null($this->isEnabled)) { $this->isEnabled = false; } return $this->isEnabled; } /** * Returns a platform integration object * * @param string $key The key name of the platform integration object, e.g. 'filesystem' * * @return object * * @since 2.1.2 */ public function getIntegrationObject($key) { $hasObject = false; if (array_key_exists($key, $this->objectCache)) { if (is_object($this->objectCache[$key])) { $hasObject = true; } } if (!$hasObject) { // Instantiate a new platform integration object $className = 'FOFIntegration' . ucfirst($this->getPlatformName()) . ucfirst($key); $this->objectCache[$key] = new $className; } return $this->objectCache[$key]; } /** * Forces a platform integration object instance * * @param string $key The key name of the platform integration object, e.g. 'filesystem' * @param object $object The object to force for this key * * @return object * * @since 2.1.2 */ public function setIntegrationObject($key, $object) { $this->objectCache[$key] = $object; } // ======================================================================== // Default implementation // ======================================================================== /** * Set the error Handling, if possible * * @param integer $level PHP error level (E_ALL) * @param string $log_level What to do with the error (ignore, callback) * @param array $options Options for the error handler * * @return void */ public function setErrorHandling($level, $log_level, $options = array()) { if (version_compare(JVERSION, '3.0', 'lt') ) { return JError::setErrorHandling($level, $log_level, $options); } } /** * Returns the base (root) directories for a given component. * * @param string $component The name of the component. For Joomla! this * is something like "com_example" * * @see FOFPlatformInterface::getComponentBaseDirs() * * @return array A hash array with keys main, alt, site and admin. */ public function getComponentBaseDirs($component) { return array( 'main' => '', 'alt' => '', 'site' => '', 'admin' => '', ); } /** * Return a list of the view template directories for this component. * * @param string $component The name of the component. For Joomla! this * is something like "com_example" * @param string $view The name of the view you're looking a * template for * @param string $layout The layout name to load, e.g. 'default' * @param string $tpl The sub-template name to load (null by default) * @param boolean $strict If true, only the specified layout will be * searched for. Otherwise we'll fall back to * the 'default' layout if the specified layout * is not found. * * @see FOFPlatformInterface::getViewTemplateDirs() * * @return array */ public function getViewTemplatePaths($component, $view, $layout = 'default', $tpl = null, $strict = false) { return array(); } /** * Get application-specific suffixes to use with template paths. This allows * you to look for view template overrides based on the application version. * * @return array A plain array of suffixes to try in template names */ public function getTemplateSuffixes() { return array(); } /** * Return the absolute path to the application's template overrides * directory for a specific component. We will use it to look for template * files instead of the regular component directorues. If the application * does not have such a thing as template overrides return an empty string. * * @param string $component The name of the component for which to fetch the overrides * @param boolean $absolute Should I return an absolute or relative path? * * @return string The path to the template overrides directory */ public function getTemplateOverridePath($component, $absolute = true) { return ''; } /** * Load the translation files for a given component. * * @param string $component The name of the component. For Joomla! this * is something like "com_example" * * @see FOFPlatformInterface::loadTranslations() * * @return void */ public function loadTranslations($component) { return null; } /** * Authorise access to the component in the back-end. * * @param string $component The name of the component. * * @see FOFPlatformInterface::authorizeAdmin() * * @return boolean True to allow loading the component, false to halt loading */ public function authorizeAdmin($component) { return true; } /** * Returns the JUser object for the current user * * @param integer $id The ID of the user to fetch * * @see FOFPlatformInterface::getUser() * * @return JDocument */ public function getUser($id = null) { return null; } /** * Returns the JDocument object which handles this component's response. * * @see FOFPlatformInterface::getDocument() * * @return JDocument */ public function getDocument() { return null; } /** * This method will try retrieving a variable from the request (input) data. * * @param string $key The user state key for the variable * @param string $request The request variable name for the variable * @param FOFInput $input The FOFInput object with the request (input) data * @param mixed $default The default value. Default: null * @param string $type The filter type for the variable data. Default: none (no filtering) * @param boolean $setUserState Should I set the user state with the fetched value? * * @see FOFPlatformInterface::getUserStateFromRequest() * * @return mixed The value of the variable */ public function getUserStateFromRequest($key, $request, $input, $default = null, $type = 'none', $setUserState = true) { return $input->get($request, $default, $type); } /** * Load plugins of a specific type. Obviously this seems to only be required * in the Joomla! CMS. * * @param string $type The type of the plugins to be loaded * * @see FOFPlatformInterface::importPlugin() * * @return void */ public function importPlugin($type) { } /** * Execute plugins (system-level triggers) and fetch back an array with * their return values. * * @param string $event The event (trigger) name, e.g. onBeforeScratchMyEar * @param array $data A hash array of data sent to the plugins as part of the trigger * * @see FOFPlatformInterface::runPlugins() * * @return array A simple array containing the results of the plugins triggered */ public function runPlugins($event, $data) { return array(); } /** * Perform an ACL check. * * @param string $action The ACL privilege to check, e.g. core.edit * @param string $assetname The asset name to check, typically the component's name * * @see FOFPlatformInterface::authorise() * * @return boolean True if the user is allowed this action */ public function authorise($action, $assetname) { return true; } /** * Is this the administrative section of the component? * * @see FOFPlatformInterface::isBackend() * * @return boolean */ public function isBackend() { return true; } /** * Is this the public section of the component? * * @see FOFPlatformInterface::isFrontend() * * @return boolean */ public function isFrontend() { return true; } /** * Is this a component running in a CLI application? * * @see FOFPlatformInterface::isCli() * * @return boolean */ public function isCli() { return true; } /** * Is AJAX re-ordering supported? This is 100% Joomla!-CMS specific. All * other platforms should return false and never ask why. * * @see FOFPlatformInterface::supportsAjaxOrdering() * * @return boolean */ public function supportsAjaxOrdering() { return true; } /** * Performs a check between two versions. Use this function instead of PHP version_compare * so we can mock it while testing * * @param string $version1 First version number * @param string $version2 Second version number * @param string $operator Operator (see version_compare for valid operators) * * @return boolean */ public function checkVersion($version1, $version2, $operator) { return version_compare($version1, $version2, $operator); } /** * Saves something to the cache. This is supposed to be used for system-wide * FOF data, not application data. * * @param string $key The key of the data to save * @param string $content The actual data to save * * @return boolean True on success */ public function setCache($key, $content) { return false; } /** * Retrieves data from the cache. This is supposed to be used for system-side * FOF data, not application data. * * @param string $key The key of the data to retrieve * @param string $default The default value to return if the key is not found or the cache is not populated * * @return string The cached value */ public function getCache($key, $default = null) { return false; } /** * Is the global FOF cache enabled? * * @return boolean */ public function isGlobalFOFCacheEnabled() { return true; } /** * Clears the cache of system-wide FOF data. You are supposed to call this in * your components' installation script post-installation and post-upgrade * methods or whenever you are modifying the structure of database tables * accessed by FOF. Please note that FOF's cache never expires and is not * purged by Joomla!. You MUST use this method to manually purge the cache. * * @return boolean True on success */ public function clearCache() { return false; } /** * logs in a user * * @param array $authInfo authentification information * * @return boolean True on success */ public function loginUser($authInfo) { return true; } /** * logs out a user * * @return boolean True on success */ public function logoutUser() { return true; } /** * Logs a deprecated practice. In Joomla! this results in the $message being output in the * deprecated log file, found in your site's log directory. * * @param $message The deprecated practice log message * * @return void */ public function logDeprecated($message) { // The default implementation does nothing. Override this in your platform classes. } /** * Returns the (internal) name of the platform implementation, e.g. * "joomla", "foobar123" etc. This MUST be the last part of the platform * class name. For example, if you have a plaform implementation class * FOFPlatformFoobar you MUST return "foobar" (all lowercase). * * @return string * * @since 2.1.2 */ public function getPlatformName() { return $this->name; } /** * Returns the version number string of the platform, e.g. "4.5.6". If * implementation integrates with a CMS or a versioned foundation (e.g. * a framework) it is advisable to return that version. * * @return string * * @since 2.1.2 */ public function getPlatformVersion() { return $this->version; } /** * Returns the human readable platform name, e.g. "Joomla!", "Joomla! * Framework", "Something Something Something Framework" etc. * * @return string * * @since 2.1.2 */ public function getPlatformHumanName() { return $this->humanReadableName; } } PK *\.] fof/platform/pwnkitnu ȯ�� PK *\.]O�J� � &