first commit

This commit is contained in:
alazhar
2020-01-02 22:20:31 +07:00
commit 10eb3340ad
5753 changed files with 631345 additions and 0 deletions

68
libraries/cms.php Normal file
View File

@ -0,0 +1,68 @@
<?php
/**
* @package Joomla.Libraries
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('_JEXEC') or die;
// Set the platform root path as a constant if necessary.
if (!defined('JPATH_PLATFORM'))
{
define('JPATH_PLATFORM', __DIR__);
}
// Import the library loader if necessary.
if (!class_exists('JLoader'))
{
require_once JPATH_PLATFORM . '/loader.php';
}
// Make sure that the Joomla Platform has been successfully loaded.
if (!class_exists('JLoader'))
{
throw new RuntimeException('Joomla Platform not loaded.');
}
// Register the library base path for CMS libraries.
JLoader::registerPrefix('J', JPATH_PLATFORM . '/cms', false, true);
// Register a handler for uncaught exceptions that shows a pretty error page when possible
set_exception_handler(array('JErrorPage', 'render'));
// Define the Joomla version if not already defined.
if (!defined('JVERSION'))
{
$jversion = new JVersion;
define('JVERSION', $jversion->getShortVersion());
}
// Set up the message queue logger for web requests
if (array_key_exists('REQUEST_METHOD', $_SERVER))
{
JLog::addLogger(array('logger' => 'messagequeue'), JLog::ALL, array('jerror'));
}
// Register classes where the names have been changed to fit the autoloader rules
// @deprecated 4.0
JLoader::register('JToolBar', JPATH_PLATFORM . '/cms/toolbar/toolbar.php');
JLoader::register('JButton', JPATH_PLATFORM . '/cms/toolbar/button.php');
JLoader::register('JInstallerComponent', JPATH_PLATFORM . '/cms/installer/adapter/component.php');
JLoader::register('JInstallerFile', JPATH_PLATFORM . '/cms/installer/adapter/file.php');
JLoader::register('JInstallerLanguage', JPATH_PLATFORM . '/cms/installer/adapter/language.php');
JLoader::register('JInstallerLibrary', JPATH_PLATFORM . '/cms/installer/adapter/library.php');
JLoader::register('JInstallerModule', JPATH_PLATFORM . '/cms/installer/adapter/module.php');
JLoader::register('JInstallerPackage', JPATH_PLATFORM . '/cms/installer/adapter/package.php');
JLoader::register('JInstallerPlugin', JPATH_PLATFORM . '/cms/installer/adapter/plugin.php');
JLoader::register('JInstallerTemplate', JPATH_PLATFORM . '/cms/installer/adapter/template.php');
JLoader::register('JExtension', JPATH_PLATFORM . '/cms/installer/extension.php');
// Register Observers:
// Add Tags to Content, Contact, NewsFeeds, WebLinks and Categories: (this is the only link between them here!):
JObserverMapper::addObserverClassToClass('JTableObserverTags', 'JTableContent', array('typeAlias' => 'com_content.article'));
JObserverMapper::addObserverClassToClass('JTableObserverTags', 'ContactTableContact', array('typeAlias' => 'com_contact.contact'));
JObserverMapper::addObserverClassToClass('JTableObserverTags', 'NewsfeedsTableNewsfeed', array('typeAlias' => 'com_newsfeeds.newsfeed'));
JObserverMapper::addObserverClassToClass('JTableObserverTags', 'WeblinksTableWeblink', array('typeAlias' => 'com_weblinks.weblink'));
JObserverMapper::addObserverClassToClass('JTableObserverTags', 'JTableCategory', array('typeAlias' => '{extension}.category'));

View File

@ -0,0 +1,348 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage Captcha
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('JPATH_PLATFORM') or die;
/**
* Joomla! Captcha base object
*
* @abstract
* @package Joomla.Libraries
* @subpackage Captcha
* @since 2.5
*/
class JCaptcha extends JObject
{
/**
* An array of Observer objects to notify
*
* @var array
* @since 2.5
*/
protected $_observers = array();
/**
* The state of the observable object
*
* @var mixed
* @since 2.5
*/
protected $_state = null;
/**
* A multi dimensional array of [function][] = key for observers
*
* @var array
* @since 2.5
*/
protected $_methods = array();
/**
* Captcha Plugin object
*
* @var JPlugin
* @since 2.5
*/
private $_captcha;
/**
* Editor Plugin name
*
* @var string
* @since 2.5
*/
private $_name;
/**
* Array of instances of this class.
*
* @var array
*/
private static $_instances = array();
/**
* Class constructor.
*
* @param string $captcha The editor to use.
* @param array $options Associative array of options.
*
* @since 2.5
*/
public function __construct($captcha, $options)
{
$this->_name = $captcha;
$this->_load($options);
}
/**
* Returns the global Captcha object, only creating it
* if it doesn't already exist.
*
* @param string $captcha The plugin to use.
* @param array $options Associative array of options.
*
* @return JCaptcha Instance of this class.
*
* @since 2.5
*/
public static function getInstance($captcha, array $options = array())
{
$signature = md5(serialize(array($captcha, $options)));
if (empty(self::$_instances[$signature]))
{
try
{
self::$_instances[$signature] = new JCaptcha($captcha, $options);
}
catch (RuntimeException $e)
{
JFactory::getApplication()->enqueueMessage($e->getMessage(), 'error');
return null;
}
}
return self::$_instances[$signature];
}
/**
* Fire the onInit event to initialise the captcha plug-in.
*
* @param string $id The id of the field.
*
* @return boolean True on success
*
* @since 2.5
*/
public function initialise($id)
{
$args['id'] = $id;
$args['event'] = 'onInit';
try
{
$this->_captcha->update($args);
}
catch (Exception $e)
{
JFactory::getApplication()->enqueueMessage($e->getMessage(), 'error');
return false;
}
return true;
}
/**
* Get the HTML for the captcha.
*
* @param string $name The control name.
* @param string $id The id for the control.
* @param string $class Value for the HTML class attribute
*
* @return mixed The return value of the function "onDisplay" of the selected Plugin.
*
* @since 2.5
*/
public function display($name, $id, $class = '')
{
// Check if captcha is already loaded.
if (is_null($this->_captcha))
{
return;
}
// Initialise the Captcha.
if (!$this->initialise($id))
{
return;
}
$args['name'] = $name;
$args['id'] = $id ? $id : $name;
$args['class'] = $class ? 'class="' . $class . '"' : '';
$args['event'] = 'onDisplay';
return $this->_captcha->update($args);
}
/**
* Checks if the answer is correct.
*
* @param string $code The answer.
*
* @return mixed The return value of the function "onCheckAnswer" of the selected Plugin.
*
* @since 2.5
*/
public function checkAnswer($code)
{
// Check if captcha is already loaded
if (is_null(($this->_captcha)))
{
return;
}
$args['code'] = $code;
$args['event'] = 'onCheckAnswer';
return $this->_captcha->update($args);
}
/**
* Load the Captcha plug-in.
*
* @param array $options Associative array of options.
*
* @return void
*
* @since 2.5
* @throws RuntimeException
*/
private function _load(array $options = array())
{
// Build the path to the needed captcha plugin
$name = JFilterInput::getInstance()->clean($this->_name, 'cmd');
$path = JPATH_PLUGINS . '/captcha/' . $name . '/' . $name . '.php';
if (!is_file($path))
{
throw new RuntimeException(JText::sprintf('JLIB_CAPTCHA_ERROR_PLUGIN_NOT_FOUND', $name));
}
// Require plugin file
require_once $path;
// Get the plugin
$plugin = JPluginHelper::getPlugin('captcha', $this->_name);
if (!$plugin)
{
throw new RuntimeException(JText::sprintf('JLIB_CAPTCHA_ERROR_PLUGIN_NOT_FOUND', $name));
}
$params = new JRegistry($plugin->params);
$plugin->params = $params;
// Build captcha plugin classname
$name = 'plgCaptcha' . $this->_name;
$this->_captcha = new $name($this, (array) $plugin, $options);
}
/**
* Get the state of the JEditor object
*
* @return mixed The state of the object.
*
* @since 2.5
*/
public function getState()
{
return $this->_state;
}
/**
* Attach an observer object
*
* @param object $observer An observer object to attach
*
* @return void
*
* @since 2.5
*/
public function attach($observer)
{
if (is_array($observer))
{
if (!isset($observer['handler']) || !isset($observer['event']) || !is_callable($observer['handler']))
{
return;
}
// Make sure we haven't already attached this array as an observer
foreach ($this->_observers as $check)
{
if (is_array($check) && $check['event'] == $observer['event'] && $check['handler'] == $observer['handler'])
{
return;
}
}
$this->_observers[] = $observer;
end($this->_observers);
$methods = array($observer['event']);
}
else
{
if (!($observer instanceof JEditor))
{
return;
}
// Make sure we haven't already attached this object as an observer
$class = get_class($observer);
foreach ($this->_observers as $check)
{
if ($check instanceof $class)
{
return;
}
}
$this->_observers[] = $observer;
$methods = array_diff(get_class_methods($observer), get_class_methods('JPlugin'));
}
$key = key($this->_observers);
foreach ($methods as $method)
{
$method = strtolower($method);
if (!isset($this->_methods[$method]))
{
$this->_methods[$method] = array();
}
$this->_methods[$method][] = $key;
}
}
/**
* Detach an observer object
*
* @param object $observer An observer object to detach.
*
* @return boolean True if the observer object was detached.
*
* @since 2.5
*/
public function detach($observer)
{
$retval = false;
$key = array_search($observer, $this->_observers);
if ($key !== false)
{
unset($this->_observers[$key]);
$retval = true;
foreach ($this->_methods as &$method)
{
$k = array_search($key, $method);
if ($k !== false)
{
unset($method[$k]);
}
}
}
return $retval;
}
}

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1,519 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage Editor
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
/**
* JEditor class to handle WYSIWYG editors
*
* @package Joomla.Libraries
* @subpackage Editor
* @since 1.5
*/
class JEditor extends JObject
{
/**
* An array of Observer objects to notify
*
* @var array
* @since 1.5
*/
protected $_observers = array();
/**
* The state of the observable object
*
* @var mixed
* @since 1.5
*/
protected $_state = null;
/**
* A multi dimensional array of [function][] = key for observers
*
* @var array
* @since 1.5
*/
protected $_methods = array();
/**
* Editor Plugin object
*
* @var object
* @since 1.5
*/
protected $_editor = null;
/**
* Editor Plugin name
*
* @var string
* @since 1.5
*/
protected $_name = null;
/**
* Object asset
*
* @var string
* @since 1.6
*/
protected $asset = null;
/**
* Object author
*
* @var string
* @since 1.6
*/
protected $author = null;
/**
* @var array JEditor instances container.
* @since 2.5
*/
protected static $instances = array();
/**
* Constructor
*
* @param string $editor The editor name
*/
public function __construct($editor = 'none')
{
$this->_name = $editor;
}
/**
* Returns the global Editor object, only creating it
* if it doesn't already exist.
*
* @param string $editor The editor to use.
*
* @return JEditor The Editor object.
*
* @since 1.5
*/
public static function getInstance($editor = 'none')
{
$signature = serialize($editor);
if (empty(self::$instances[$signature]))
{
self::$instances[$signature] = new JEditor($editor);
}
return self::$instances[$signature];
}
/**
* Get the state of the JEditor object
*
* @return mixed The state of the object.
*
* @since 1.5
*/
public function getState()
{
return $this->_state;
}
/**
* Attach an observer object
*
* @param object $observer An observer object to attach
*
* @return void
*
* @since 1.5
*/
public function attach($observer)
{
if (is_array($observer))
{
if (!isset($observer['handler']) || !isset($observer['event']) || !is_callable($observer['handler']))
{
return;
}
// Make sure we haven't already attached this array as an observer
foreach ($this->_observers as $check)
{
if (is_array($check) && $check['event'] == $observer['event'] && $check['handler'] == $observer['handler'])
{
return;
}
}
$this->_observers[] = $observer;
end($this->_observers);
$methods = array($observer['event']);
}
else
{
if (!($observer instanceof JEditor))
{
return;
}
// Make sure we haven't already attached this object as an observer
$class = get_class($observer);
foreach ($this->_observers as $check)
{
if ($check instanceof $class)
{
return;
}
}
$this->_observers[] = $observer;
$methods = array_diff(get_class_methods($observer), get_class_methods('JPlugin'));
}
$key = key($this->_observers);
foreach ($methods as $method)
{
$method = strtolower($method);
if (!isset($this->_methods[$method]))
{
$this->_methods[$method] = array();
}
$this->_methods[$method][] = $key;
}
}
/**
* Detach an observer object
*
* @param object $observer An observer object to detach.
*
* @return boolean True if the observer object was detached.
*
* @since 1.5
*/
public function detach($observer)
{
$retval = false;
$key = array_search($observer, $this->_observers);
if ($key !== false)
{
unset($this->_observers[$key]);
$retval = true;
foreach ($this->_methods as &$method)
{
$k = array_search($key, $method);
if ($k !== false)
{
unset($method[$k]);
}
}
}
return $retval;
}
/**
* Initialise the editor
*
* @return void
*
* @since 1.5
*/
public function initialise()
{
// Check if editor is already loaded
if (is_null(($this->_editor)))
{
return;
}
$args['event'] = 'onInit';
$return = '';
$results[] = $this->_editor->update($args);
foreach ($results as $result)
{
if (trim($result))
{
// @todo remove code: $return .= $result;
$return = $result;
}
}
$document = JFactory::getDocument();
$document->addCustomTag($return);
}
/**
* Display the editor area.
*
* @param string $name The control name.
* @param string $html The contents of the text area.
* @param string $width The width of the text area (px or %).
* @param string $height The height of the text area (px or %).
* @param integer $col The number of columns for the textarea.
* @param integer $row The number of rows for the textarea.
* @param boolean $buttons True and the editor buttons will be displayed.
* @param string $id An optional ID for the textarea (note: since 1.6). If not supplied the name is used.
* @param string $asset The object asset
* @param object $author The author.
* @param array $params Associative array of editor parameters.
*
* @return string
*
* @since 1.5
*/
public function display($name, $html, $width, $height, $col, $row, $buttons = true, $id = null, $asset = null, $author = null, $params = array())
{
$this->asset = $asset;
$this->author = $author;
$this->_loadEditor($params);
// Check whether editor is already loaded
if (is_null(($this->_editor)))
{
return;
}
// Backwards compatibility. Width and height should be passed without a semicolon from now on.
// If editor plugins need a unit like "px" for CSS styling, they need to take care of that
$width = str_replace(';', '', $width);
$height = str_replace(';', '', $height);
$return = null;
$args['name'] = $name;
$args['content'] = $html;
$args['width'] = $width;
$args['height'] = $height;
$args['col'] = $col;
$args['row'] = $row;
$args['buttons'] = $buttons;
$args['id'] = $id ? $id : $name;
$args['event'] = 'onDisplay';
$results[] = $this->_editor->update($args);
foreach ($results as $result)
{
if (trim($result))
{
$return .= $result;
}
}
return $return;
}
/**
* Save the editor content
*
* @param string $editor The name of the editor control
*
* @return string
*
* @since 1.5
*/
public function save($editor)
{
$this->_loadEditor();
// Check whether editor is already loaded
if (is_null(($this->_editor)))
{
return;
}
$args[] = $editor;
$args['event'] = 'onSave';
$return = '';
$results[] = $this->_editor->update($args);
foreach ($results as $result)
{
if (trim($result))
{
$return .= $result;
}
}
return $return;
}
/**
* Get the editor contents
*
* @param string $editor The name of the editor control
*
* @return string
*
* @since 1.5
*/
public function getContent($editor)
{
$this->_loadEditor();
$args['name'] = $editor;
$args['event'] = 'onGetContent';
$return = '';
$results[] = $this->_editor->update($args);
foreach ($results as $result)
{
if (trim($result))
{
$return .= $result;
}
}
return $return;
}
/**
* Set the editor contents
*
* @param string $editor The name of the editor control
* @param string $html The contents of the text area
*
* @return string
*
* @since 1.5
*/
public function setContent($editor, $html)
{
$this->_loadEditor();
$args['name'] = $editor;
$args['html'] = $html;
$args['event'] = 'onSetContent';
$return = '';
$results[] = $this->_editor->update($args);
foreach ($results as $result)
{
if (trim($result))
{
$return .= $result;
}
}
return $return;
}
/**
* Get the editor extended buttons (usually from plugins)
*
* @param string $editor The name of the editor.
* @param mixed $buttons Can be boolean or array, if boolean defines if the buttons are
* displayed, if array defines a list of buttons not to show.
*
* @return array
*
* @since 1.5
*/
public function getButtons($editor, $buttons = true)
{
$result = array();
if (is_bool($buttons) && !$buttons)
{
return $result;
}
// Get plugins
$plugins = JPluginHelper::getPlugin('editors-xtd');
foreach ($plugins as $plugin)
{
if (is_array($buttons) && in_array($plugin->name, $buttons))
{
continue;
}
JPluginHelper::importPlugin('editors-xtd', $plugin->name, false);
$className = 'plgButton' . $plugin->name;
if (class_exists($className))
{
$plugin = new $className($this, (array) $plugin);
}
// Try to authenticate
if ($temp = $plugin->onDisplay($editor, $this->asset, $this->author))
{
$result[] = $temp;
}
}
return $result;
}
/**
* Load the editor
*
* @param array $config Associative array of editor config paramaters
*
* @return mixed
*
* @since 1.5
*/
protected function _loadEditor($config = array())
{
// Check whether editor is already loaded
if (!is_null(($this->_editor)))
{
return;
}
// Build the path to the needed editor plugin
$name = JFilterInput::getInstance()->clean($this->_name, 'cmd');
$path = JPATH_PLUGINS . '/editors/' . $name . '.php';
if (!is_file($path))
{
$path = JPATH_PLUGINS . '/editors/' . $name . '/' . $name . '.php';
if (!is_file($path))
{
JLog::add(JText::_('JLIB_HTML_EDITOR_CANNOT_LOAD'), JLog::WARNING, 'jerror');
return false;
}
}
// Require plugin file
require_once $path;
// Get the plugin
$plugin = JPluginHelper::getPlugin('editors', $this->_name);
$params = new JRegistry;
$params->loadString($plugin->params);
$params->loadArray($config);
$plugin->params = $params;
// Build editor plugin classname
$name = 'plgEditor' . $this->_name;
if ($this->_editor = new $name($this, (array) $plugin))
{
// Load plugin parameters
$this->initialise();
JPluginHelper::importPlugin('editors-xtd');
}
}
}

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1,83 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage Error
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('JPATH_BASE') or die;
/**
* Displays the custom error page when an uncaught exception occurs.
*
* @package Joomla.Libraries
* @subpackage Error
* @since 3.0
*/
class JErrorPage
{
/**
* Render the error page based on an exception.
*
* @param Exception $error The exception for which to render the error page.
*
* @return void
*
* @since 3.0
*/
public static function render(Exception $error)
{
try
{
$app = JFactory::getApplication();
$document = JDocument::getInstance('error');
if (!$document)
{
// We're probably in an CLI environment
exit($error->getMessage());
$app->close(0);
}
$config = JFactory::getConfig();
// Get the current template from the application
$template = $app->getTemplate();
// Push the error object into the document
$document->setError($error);
if (ob_get_contents())
{
ob_end_clean();
}
$document->setTitle(JText::_('Error') . ': ' . $error->getCode());
$data = $document->render(
false,
array('template' => $template,
'directory' => JPATH_THEMES,
'debug' => $config->get('debug'))
);
// Failsafe to get the error displayed.
if (empty($data))
{
exit($error->getMessage());
}
else
{
// Do not allow cache
JResponse::allowCache(false);
JResponse::setBody($data);
echo JResponse::toString();
}
}
catch (Exception $e)
{
exit('Error displaying the error page: ' . $e->getMessage());
}
}
}

View File

@ -0,0 +1,96 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage Form
*
* @copyright Copyright (C) 2005 - 2009 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('JPATH_BASE') or die;
/**
* Form Field class for the Joomla Framework.
*
* @package Joomla.Libraries
* @subpackage Form
* @since 2.5
*/
class JFormFieldCaptcha extends JFormField
{
/**
* The field type.
*
* @var string
*/
protected $type = 'Captcha';
/**
* Method to attach a JForm object to the field.
*
* @param SimpleXMLElement $element The SimpleXMLElement object representing the <field /> tag for the form field object.
* @param mixed $value The form field value to validate.
* @param string $group The field name group control value. This acts as as an array container for the field.
* For example if the field has name="foo" and the group value is set to "bar" then the
* full field name would end up being "bar[foo]".
*
* @return boolean True on success.
*
* @since 2.5
*/
public function setup(SimpleXMLElement $element, $value, $group = null)
{
$result = parent::setup($element, $value, $group);
$plugin = $this->element['plugin'] ?
(string) $this->element['plugin'] :
JFactory::getApplication()->getParams()->get('captcha', JFactory::getConfig()->get('captcha'));
if ($plugin === 0 || $plugin === '0' || $plugin === '' || $plugin === null)
{
$this->hidden = true;
}
else
{
// Force field to be required. There's no reason to have a captcha if it is not required.
// Obs: Don't put required="required" in the xml file, you just need to have validate="captcha"
$this->required = true;
$class = $this->element['class'];
if (strpos($class, 'required') === false)
{
$this->element['class'] = $class . ' required';
}
}
return $result;
}
/**
* Method to get the field input.
*
* @return string The field input.
*
* @since 2.5
*/
protected function getInput()
{
$class = $this->element['class'] ? (string) $this->element['class'] : '';
$plugin = $this->element['plugin'] ? (string) $this->element['plugin'] : JFactory::getApplication()->getParams()->get('captcha', JFactory::getConfig()->get('captcha'));
$namespace = $this->element['namespace'] ? (string) $this->element['namespace'] : $this->form->getName();
// Use 0 for none
if ($plugin === 0 || $plugin === '0' || $plugin === '' || $plugin === null)
{
return '';
}
else
{
if (($captcha = JCaptcha::getInstance($plugin, array('namespace' => $namespace))) == null)
{
return '';
}
}
return $captcha->display($this->name, $this->id, $class);
}
}

View File

@ -0,0 +1,120 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage Form
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
JFormHelper::loadFieldClass('groupedlist');
/**
* Chrome Styles Form Field class for the Joomla Platform.
*
* @package Joomla.Libraries
* @subpackage Form
* @since 3.0
*/
class JFormFieldChromeStyle extends JFormFieldGroupedList
{
/**
* The form field type.
*
* @var string
* @since 3.0
*/
public $type = 'ChromeStyle';
/**
* Method to get the list of template chrome style options
* grouped by template.
*
* @return array The field option objects as a nested array in groups.
*
* @since 3.0
*/
protected function getGroups()
{
$groups = array();
// Add Module Style Field
$tmp = '---' . JText::_('JLIB_FORM_VALUE_FROM_TEMPLATE') . '---';
$groups[$tmp][] = JHtml::_('select.option', '0', JText::_('JLIB_FORM_VALUE_INHERITED'));
$templateStyles = $this->getTemplateModuleStyles();
// Create one new option object for each available style, grouped by templates
foreach ($templateStyles as $template => $styles)
{
$template = ucfirst($template);
$groups[$template] = array();
foreach ($styles as $style)
{
$tmp = JHtml::_('select.option', $template . '-' . $style, $style);
$groups[$template][] = $tmp;
}
}
reset($groups);
return $groups;
}
/**
* Method to get the templates module styles.
*
* @return array The array of styles, grouped by templates.
*
* @since 3.0
*/
protected function getTemplateModuleStyles()
{
$moduleStyles = array();
$templates = array($this->getSystemTemplate());
$templates = array_merge($templates, ModulesHelper::getTemplates('site'));
foreach ($templates as $template)
{
$modulesFilePath = JPATH_SITE . '/templates/' . $template->element . '/html/modules.php';
// Is there modules.php for that template?
if (file_exists($modulesFilePath))
{
$modulesFileData = file_get_contents($modulesFilePath);
preg_match_all('/function[\s\t]*modChrome\_([a-z0-9\-\_]*)[\s\t]*\(/i', $modulesFileData, $styles);
if (!array_key_exists($template->element, $moduleStyles))
{
$moduleStyles[$template->element] = array();
}
$moduleStyles[$template->element] = $styles[1];
}
}
return $moduleStyles;
}
/**
* Method to get the system template as an object.
*
* @return array The object of system template.
*
* @since 3.0
*/
protected function getSystemTemplate()
{
$template = new stdClass;
$template->element = 'system';
$template->name = 'system';
$template->enabled = 1;
return $template;
}
}

View File

@ -0,0 +1,44 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage Form
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
JFormHelper::loadFieldClass('list');
/**
* Form Field class for the Joomla Platform.
* Provides a list of content languages
*
* @package Joomla.Libraries
* @subpackage Form
* @see JFormFieldLanguage for a select list of application languages.
* @since 1.6
*/
class JFormFieldContentlanguage extends JFormFieldList
{
/**
* The form field type.
*
* @var string
* @since 1.6
*/
public $type = 'ContentLanguage';
/**
* Method to get the field options for content languages.
*
* @return array The options the field is going to show.
*
* @since 1.6
*/
protected function getOptions()
{
return array_merge(parent::getOptions(), JHtml::_('contentlanguage.existing'));
}
}

View File

@ -0,0 +1,98 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage Form
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('JPATH_BASE') or die;
JFormHelper::loadFieldClass('list');
/**
* Form Field class for the Joomla Framework.
*
* @package Joomla.Libraries
* @subpackage Form
* @since 3.1
*/
class JFormFieldContenttype extends JFormFieldList
{
/**
* A flexible tag list that respects access controls
*
* @var string
* @since 3.1
*/
public $type = 'Contenttype';
/**
* Method to get the field input for a list of content types.
*
* @return string The field input.
*
* @since 3.1
*/
protected function getInput()
{
if (!is_array($this->value))
{
if (is_object($this->value))
{
$this->value = $this->value->tags;
}
if (is_string($this->value))
{
$this->value = explode(',', $this->value);
}
}
$input = parent::getInput();
return $input;
}
/**
* Method to get a list of content types
*
* @return array The field option objects.
*
* @since 3.1
*/
protected function getOptions()
{
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select('a.type_id AS value, a.type_title AS text')
->from('#__content_types AS a')
->order('a.type_title ASC');
// Get the options.
$db->setQuery($query);
try
{
$options = $db->loadObjectList();
}
catch (RuntimeException $e)
{
return false;
}
// Merge any additional options in the XML definition.
$options = array_merge(parent::getOptions(), $options);
foreach ($options as $option)
{
$option->text = mb_strtoupper(str_replace(' ', '_', $option->text), 'UTF-8');
$option->text = 'COM_TAGS_CONTENT_TYPE_' . $option->text;
$option->text = JText::_($option->text);
}
return $options;
}
}

View File

@ -0,0 +1,156 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage Form
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
/**
* Form Field class for the Joomla Platform.
* An editarea field for content creation
*
* @package Joomla.Libraries
* @subpackage Form
* @see JEditor
* @since 1.6
*/
class JFormFieldEditor extends JFormField
{
/**
* The form field type.
*
* @var string
* @since 1.6
*/
public $type = 'Editor';
/**
* The JEditor object.
*
* @var JEditor
* @since 1.6
*/
protected $editor;
/**
* Method to get the field input markup for the editor area
*
* @return string The field input markup.
*
* @since 1.6
*/
protected function getInput()
{
$rows = (int) $this->element['rows'];
$cols = (int) $this->element['cols'];
$height = ((string) $this->element['height']) ? (string) $this->element['height'] : '250';
$width = ((string) $this->element['width']) ? (string) $this->element['width'] : '100%';
$assetField = $this->element['asset_field'] ? (string) $this->element['asset_field'] : 'asset_id';
$authorField = $this->element['created_by_field'] ? (string) $this->element['created_by_field'] : 'created_by';
$asset = $this->form->getValue($assetField) ? $this->form->getValue($assetField) : (string) $this->element['asset_id'];
// Build the buttons array.
$buttons = (string) $this->element['buttons'];
if ($buttons == 'true' || $buttons == 'yes' || $buttons == '1')
{
$buttons = true;
}
elseif ($buttons == 'false' || $buttons == 'no' || $buttons == '0')
{
$buttons = false;
}
else
{
$buttons = explode(',', $buttons);
}
$hide = ((string) $this->element['hide']) ? explode(',', (string) $this->element['hide']) : array();
// Get an editor object.
$editor = $this->getEditor();
return $editor
->display(
$this->name, htmlspecialchars($this->value, ENT_COMPAT, 'UTF-8'), $width, $height, $cols, $rows,
$buttons ? (is_array($buttons) ? array_merge($buttons, $hide) : $hide) : false, $this->id, $asset,
$this->form->getValue($authorField)
);
}
/**
* Method to get a JEditor object based on the form field.
*
* @return JEditor The JEditor object.
*
* @since 1.6
*/
protected function getEditor()
{
// Only create the editor if it is not already created.
if (empty($this->editor))
{
$editor = null;
// Get the editor type attribute. Can be in the form of: editor="desired|alternative".
$type = trim((string) $this->element['editor']);
if ($type)
{
// Get the list of editor types.
$types = explode('|', $type);
// Get the database object.
$db = JFactory::getDbo();
// Iterate over teh types looking for an existing editor.
foreach ($types as $element)
{
// Build the query.
$query = $db->getQuery(true)
->select('element')
->from('#__extensions')
->where('element = ' . $db->quote($element))
->where('folder = ' . $db->quote('editors'))
->where('enabled = 1');
// Check of the editor exists.
$db->setQuery($query, 0, 1);
$editor = $db->loadResult();
// If an editor was found stop looking.
if ($editor)
{
break;
}
}
}
// Create the JEditor instance based on the given editor.
if (is_null($editor))
{
$conf = JFactory::getConfig();
$editor = $conf->get('editor');
}
$this->editor = JEditor::getInstance($editor);
}
return $this->editor;
}
/**
* Method to get the JEditor output for an onSave event.
*
* @return string The JEditor object output.
*
* @since 1.6
*/
public function save()
{
return $this->getEditor()->save($this->id);
}
}

View File

@ -0,0 +1,54 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage Form
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('JPATH_BASE') or die;
JFormHelper::loadFieldClass('list');
/**
* Form Field class for the Joomla! CMS.
*
* @package Joomla.Libraries
* @subpackage Form
* @since 3.0
*/
class JFormFieldHeadertag extends JFormFieldList
{
/**
* The form field type.
*
* @var string
* @since 3.0
*/
protected $type = 'HeaderTag';
/**
* Method to get the field options.
*
* @return array The field option objects.
*
* @since 3.0
*/
protected function getOptions()
{
$options = array();
$tags = array('h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p');
// Create one new option object for each tag
foreach ($tags as $tag)
{
$tmp = JHtml::_('select.option', $tag, $tag);
$options[] = $tmp;
}
reset($options);
return $options;
}
}

View File

@ -0,0 +1,46 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage Form
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
JFormHelper::loadFieldClass('list');
/**
* Form Field class for the Joomla Platform.
* Provides a select list of help sites.
*
* @package Joomla.Libraries
* @subpackage Form
* @since 1.6.0
*/
class JFormFieldHelpsite extends JFormFieldList
{
/**
* The form field type.
*
* @var string
* @since 1.6.0
*/
public $type = 'Helpsite';
/**
* Method to get the help site field options.
*
* @return array The field option objects.
*
* @since 1.6.0
*/
protected function getOptions()
{
// Merge any additional options in the XML definition.
$options = array_merge(parent::getOptions(), JHelp::createSiteList(JPATH_ADMINISTRATOR . '/help/helpsites.xml', $this->value));
return $options;
}
}

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1,239 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage Form
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
/**
* Form Field class for the Joomla Platform.
* Provides a modal media selector including upload mechanism
*
* @package Joomla.Libraries
* @subpackage Form
* @since 1.6
*/
class JFormFieldMedia extends JFormField
{
/**
* The form field type.
*
* @var string
* @since 1.6
*/
protected $type = 'Media';
/**
* The initialised state of the document object.
*
* @var boolean
* @since 1.6
*/
protected static $initialised = false;
/**
* Method to get the field input markup for a media selector.
* Use attributes to identify specific created_by and asset_id fields
*
* @return string The field input markup.
*
* @since 1.6
*/
protected function getInput()
{
$assetField = $this->element['asset_field'] ? (string) $this->element['asset_field'] : 'asset_id';
$authorField = $this->element['created_by_field'] ? (string) $this->element['created_by_field'] : 'created_by';
$asset = $this->form->getValue($assetField) ? $this->form->getValue($assetField) : (string) $this->element['asset_id'];
if ($asset == '')
{
$asset = JFactory::getApplication()->input->get('option');
}
$link = (string) $this->element['link'];
if (!self::$initialised)
{
// Load the modal behavior script.
JHtml::_('behavior.modal');
// Build the script.
$script = array();
$script[] = ' function jInsertFieldValue(value, id) {';
$script[] = ' var old_value = document.id(id).value;';
$script[] = ' if (old_value != value) {';
$script[] = ' var elem = document.id(id);';
$script[] = ' elem.value = value;';
$script[] = ' elem.fireEvent("change");';
$script[] = ' if (typeof(elem.onchange) === "function") {';
$script[] = ' elem.onchange();';
$script[] = ' }';
$script[] = ' jMediaRefreshPreview(id);';
$script[] = ' }';
$script[] = ' }';
$script[] = ' function jMediaRefreshPreview(id) {';
$script[] = ' var value = document.id(id).value;';
$script[] = ' var img = document.id(id + "_preview");';
$script[] = ' if (img) {';
$script[] = ' if (value) {';
$script[] = ' img.src = "' . JUri::root() . '" + value;';
$script[] = ' document.id(id + "_preview_empty").setStyle("display", "none");';
$script[] = ' document.id(id + "_preview_img").setStyle("display", "");';
$script[] = ' } else { ';
$script[] = ' img.src = ""';
$script[] = ' document.id(id + "_preview_empty").setStyle("display", "");';
$script[] = ' document.id(id + "_preview_img").setStyle("display", "none");';
$script[] = ' } ';
$script[] = ' } ';
$script[] = ' }';
$script[] = ' function jMediaRefreshPreviewTip(tip)';
$script[] = ' {';
$script[] = ' var img = tip.getElement("img.media-preview");';
$script[] = ' tip.getElement("div.tip").setStyle("max-width", "none");';
$script[] = ' var id = img.getProperty("id");';
$script[] = ' id = id.substring(0, id.length - "_preview".length);';
$script[] = ' jMediaRefreshPreview(id);';
$script[] = ' tip.setStyle("display", "block");';
$script[] = ' }';
// Add the script to the document head.
JFactory::getDocument()->addScriptDeclaration(implode("\n", $script));
self::$initialised = true;
}
$html = array();
$attr = '';
// Initialize some field attributes.
$attr .= $this->element['class'] ? ' class="' . (string) $this->element['class'] . '"' : '';
$attr .= $this->element['size'] ? ' size="' . (int) $this->element['size'] . '"' : '';
// Initialize JavaScript field attributes.
$attr .= $this->element['onchange'] ? ' onchange="' . (string) $this->element['onchange'] . '"' : '';
// The text field.
$html[] = '<div class="input-prepend input-append">';
// The Preview.
$preview = (string) $this->element['preview'];
$showPreview = true;
$showAsTooltip = false;
switch ($preview)
{
case 'no': // Deprecated parameter value
case 'false':
case 'none':
$showPreview = false;
break;
case 'yes': // Deprecated parameter value
case 'true':
case 'show':
break;
case 'tooltip':
default:
$showAsTooltip = true;
$options = array(
'onShow' => 'jMediaRefreshPreviewTip',
);
JHtml::_('behavior.tooltip', '.hasTipPreview', $options);
break;
}
if ($showPreview)
{
if ($this->value && file_exists(JPATH_ROOT . '/' . $this->value))
{
$src = JUri::root() . $this->value;
}
else
{
$src = '';
}
$width = isset($this->element['preview_width']) ? (int) $this->element['preview_width'] : 300;
$height = isset($this->element['preview_height']) ? (int) $this->element['preview_height'] : 200;
$style = '';
$style .= ($width > 0) ? 'max-width:' . $width . 'px;' : '';
$style .= ($height > 0) ? 'max-height:' . $height . 'px;' : '';
$imgattr = array(
'id' => $this->id . '_preview',
'class' => 'media-preview',
'style' => $style,
);
$img = JHtml::image($src, JText::_('JLIB_FORM_MEDIA_PREVIEW_ALT'), $imgattr);
$previewImg = '<div id="' . $this->id . '_preview_img"' . ($src ? '' : ' style="display:none"') . '>' . $img . '</div>';
$previewImgEmpty = '<div id="' . $this->id . '_preview_empty"' . ($src ? ' style="display:none"' : '') . '>'
. JText::_('JLIB_FORM_MEDIA_PREVIEW_EMPTY') . '</div>';
if ($showAsTooltip)
{
$html[] = '<div class="media-preview add-on">';
$tooltip = $previewImgEmpty . $previewImg;
$options = array(
'title' => JText::_('JLIB_FORM_MEDIA_PREVIEW_SELECTED_IMAGE'),
'text' => '<i class="icon-eye"></i>',
'class' => 'hasTipPreview'
);
$html[] = JHtml::tooltip($tooltip, $options);
$html[] = '</div>';
}
else
{
$html[] = '<div class="media-preview add-on" style="height:auto">';
$html[] = ' ' . $previewImgEmpty;
$html[] = ' ' . $previewImg;
$html[] = '</div>';
}
}
$html[] = ' <input type="text" class="input-small" name="' . $this->name . '" id="' . $this->id . '" value="'
. htmlspecialchars($this->value, ENT_COMPAT, 'UTF-8') . '" readonly="readonly"' . $attr . ' />';
$directory = (string) $this->element['directory'];
if ($this->value && file_exists(JPATH_ROOT . '/' . $this->value))
{
$folder = explode('/', $this->value);
$folder = array_diff_assoc($folder, explode('/', JComponentHelper::getParams('com_media')->get('image_path', 'images')));
array_pop($folder);
$folder = implode('/', $folder);
}
elseif (file_exists(JPATH_ROOT . '/' . JComponentHelper::getParams('com_media')->get('image_path', 'images') . '/' . $directory))
{
$folder = $directory;
}
else
{
$folder = '';
}
// The button.
if ($this->element['disabled'] != true)
{
JHtml::_('bootstrap.tooltip');
$html[] = '<a class="modal btn" title="' . JText::_('JLIB_FORM_BUTTON_SELECT') . '" href="'
. ($this->element['readonly'] ? ''
: ($link ? $link
: 'index.php?option=com_media&amp;view=images&amp;tmpl=component&amp;asset=' . $asset . '&amp;author='
. $this->form->getValue($authorField)) . '&amp;fieldid=' . $this->id . '&amp;folder=' . $folder) . '"'
. ' rel="{handler: \'iframe\', size: {x: 800, y: 500}}">';
$html[] = JText::_('JLIB_FORM_BUTTON_SELECT') . '</a><a class="btn hasTooltip" title="' . JText::_('JLIB_FORM_BUTTON_CLEAR') . '" href="#" onclick="';
$html[] = 'jInsertFieldValue(\'\', \'' . $this->id . '\');';
$html[] = 'return false;';
$html[] = '">';
$html[] = '<i class="icon-remove"></i></a>';
}
$html[] = '</div>';
return implode("\n", $html);
}
}

View File

@ -0,0 +1,48 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage Form
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
JFormHelper::loadFieldClass('list');
// Import the com_menus helper.
require_once realpath(JPATH_ADMINISTRATOR . '/components/com_menus/helpers/menus.php');
/**
* Supports an HTML select list of menus
*
* @package Joomla.Libraries
* @subpackage Form
* @since 1.6
*/
class JFormFieldMenu extends JFormFieldList
{
/**
* The form field type.
*
* @var string
* @since 1.6
*/
public $type = 'Menu';
/**
* Method to get the list of menus for the field options.
*
* @return array The field option objects.
*
* @since 1.6
*/
protected function getOptions()
{
// Merge any additional options in the XML definition.
$options = array_merge(parent::getOptions(), JHtml::_('menu.menus'));
return $options;
}
}

View File

@ -0,0 +1,91 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage Form
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
JFormHelper::loadFieldClass('groupedlist');
// Import the com_menus helper.
require_once realpath(JPATH_ADMINISTRATOR . '/components/com_menus/helpers/menus.php');
/**
* Supports an HTML grouped select list of menu item grouped by menu
*
* @package Joomla.Libraries
* @subpackage Form
* @since 1.6
*/
class JFormFieldMenuitem extends JFormFieldGroupedList
{
/**
* The form field type.
*
* @var string
* @since 1.6
*/
public $type = 'MenuItem';
/**
* Method to get the field option groups.
*
* @return array The field option objects as a nested array in groups.
*
* @since 1.6
*/
protected function getGroups()
{
$groups = array();
// Initialize some field attributes.
$menuType = (string) $this->element['menu_type'];
$published = $this->element['published'] ? explode(',', (string) $this->element['published']) : array();
$disable = $this->element['disable'] ? explode(',', (string) $this->element['disable']) : array();
$language = $this->element['language'] ? explode(',', (string) $this->element['language']) : array();
// Get the menu items.
$items = MenusHelper::getMenuLinks($menuType, 0, 0, $published, $language);
// Build group for a specific menu type.
if ($menuType)
{
// Initialize the group.
$groups[$menuType] = array();
// Build the options array.
foreach ($items as $link)
{
$groups[$menuType][] = JHtml::_('select.option', $link->value, $link->text, 'value', 'text', in_array($link->type, $disable));
}
}
// Build groups for all menu types.
else
{
// Build the groups arrays.
foreach ($items as $menu)
{
// Initialize the group.
$groups[$menu->menutype] = array();
// Build the options array.
foreach ($menu->links as $link)
{
$groups[$menu->menutype][] = JHtml::_(
'select.option', $link->value, $link->text, 'value', 'text',
in_array($link->type, $disable)
);
}
}
}
// Merge any additional groups in the XML definition.
$groups = array_merge(parent::getGroups(), $groups);
return $groups;
}
}

View File

@ -0,0 +1,96 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage Form
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('JPATH_BASE') or die;
/**
* Form Field class for the Joomla! CMS.
*
* @package Joomla.Libraries
* @subpackage Form
* @since 1.6
*/
class JFormFieldModuleOrder extends JFormField
{
/**
* The form field type.
*
* @var string
* @since 1.6
*/
protected $type = 'ModuleOrder';
/**
* Method to get the field input markup.
*
* @return string The field input markup.
*
* @since 1.6
*/
protected function getInput()
{
$html = array();
$attr = '';
// Initialize some field attributes.
$attr .= $this->element['class'] ? ' class="' . (string) $this->element['class'] . '"' : '';
$attr .= ((string) $this->element['disabled'] == 'true') ? ' disabled="disabled"' : '';
$attr .= $this->element['size'] ? ' size="' . (int) $this->element['size'] . '"' : '';
// Initialize JavaScript field attributes.
$attr .= $this->element['onchange'] ? ' onchange="' . (string) $this->element['onchange'] . '"' : '';
$html[] = '<script type="text/javascript">';
$ordering = $this->form->getValue('ordering');
$position = $this->form->getValue('position');
$clientId = $this->form->getValue('client_id');
$html[] = 'var originalOrder = "' . $ordering . '";';
$html[] = 'var originalPos = "' . $position . '";';
$html[] = 'var orders = new Array();';
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select('position, ordering, title')
->from('#__modules')
->where('client_id = ' . (int) $clientId)
->order('ordering');
$db->setQuery($query);
try
{
$orders = $db->loadObjectList();
}
catch (RuntimeException $e)
{
JError::raiseWarning(500, $e->getMessage());
return false;
}
$orders2 = array();
for ($i = 0, $n = count($orders); $i < $n; $i++)
{
if (!isset($orders2[$orders[$i]->position]))
{
$orders2[$orders[$i]->position] = 0;
}
$orders2[$orders[$i]->position]++;
$ord = $orders2[$orders[$i]->position];
$title = JText::sprintf('COM_MODULES_OPTION_ORDER_POSITION', $ord, addslashes($orders[$i]->title));
$html[] = 'orders[' . $i . '] = new Array("' . $orders[$i]->position . '","' . $ord . '","' . $title . '");';
}
$html[] = 'writeDynaList(\'name="' . $this->name . '" id="' . $this->id . '"' . $attr . '\', orders, originalPos, originalPos, originalOrder);';
$html[] = '</script>';
return implode("\n", $html);
}
}

View File

@ -0,0 +1,86 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage Form
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('JPATH_BASE') or die;
JFormHelper::loadFieldClass('text');
/**
* Form Field class for the Joomla! CMS.
*
* @package Joomla.Libraries
* @subpackage Form
* @since 1.6
*/
class JFormFieldModulePosition extends JFormFieldText
{
/**
* The form field type.
*
* @var string
* @since 1.6
*/
protected $type = 'ModulePosition';
/**
* Method to get the field input markup.
*
* @return string The field input markup.
*
* @since 1.6
*/
protected function getInput()
{
// Get the client id.
$clientId = $this->element['client_id'];
if (!isset($clientId))
{
$clientName = $this->element['client'];
if (isset($clientName))
{
$client = JApplicationHelper::getClientInfo($clientName, true);
$clientId = $client->id;
}
}
if (!isset($clientId) && $this->form instanceof JForm)
{
$clientId = $this->form->getValue('client_id');
}
$clientId = (int) $clientId;
// Load the modal behavior script.
JHtml::_('behavior.modal', 'a.modal');
// Build the script.
$script = array();
$script[] = ' function jSelectPosition_' . $this->id . '(name) {';
$script[] = ' document.id("' . $this->id . '").value = name;';
$script[] = ' SqueezeBox.close();';
$script[] = ' }';
// Add the script to the document head.
JFactory::getDocument()->addScriptDeclaration(implode("\n", $script));
// Setup variables for display.
$html = array();
$link = 'index.php?option=com_modules&view=positions&layout=modal&tmpl=component&function=jSelectPosition_' . $this->id . '&amp;client_id=' . $clientId;
// The current user display field.
$html[] = '<div class="input-append">';
$html[] = parent::getInput()
. '<a class="btn modal" title="' . JText::_('COM_MODULES_CHANGE_POSITION_TITLE') . '" href="' . $link . '" rel="{handler: \'iframe\', size: {x: 800, y: 450}}">'
. '<i class="icon-screenshot"></i> '
. JText::_('COM_MODULES_CHANGE_POSITION_BUTTON') . '</a>';
$html[] = '</div>';
return implode("\n", $html);
}
}

View File

@ -0,0 +1,54 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage Form
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('JPATH_BASE') or die;
JFormHelper::loadFieldClass('list');
/**
* Form Field class for the Joomla! CMS.
*
* @package Joomla.Libraries
* @subpackage Form
* @since 3.0
*/
class JFormFieldModuletag extends JFormFieldList
{
/**
* The form field type.
*
* @var string
* @since 3.0
*/
protected $type = 'ModuleTag';
/**
* Method to get the field options.
*
* @return array The field option objects.
*
* @since 3.0
*/
protected function getOptions()
{
$options = array();
$tags = array('div', 'section', 'aside', 'nav', 'address', 'article');
// Create one new option object for each tag
foreach ($tags as $tag)
{
$tmp = JHtml::_('select.option', $tag, $tag);
$options[] = $tmp;
}
reset($options);
return $options;
}
}

View File

@ -0,0 +1,241 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage Form
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('JPATH_BASE') or die;
JFormHelper::loadFieldClass('list');
/**
* Form Field class for the Joomla Framework.
*
* @package Joomla.Libraries
* @subpackage Form
* @since 3.1
*/
class JFormFieldTag extends JFormFieldList
{
/**
* A flexible tag list that respects access controls
*
* @var string
* @since 3.1
*/
public $type = 'Tag';
/**
* Flag to work with nested tag field
*
* @var boolean
* @since 3.1
*/
public $isNested = null;
/**
* com_tags parameters
*
* @var JRegistry
* @since 3.1
*/
protected $comParams = null;
/**
* Constructor
*
* @since 3.1
*/
public function __construct()
{
parent::__construct();
// Load com_tags config
$this->comParams = JComponentHelper::getParams('com_tags');
}
/**
* Method to get the field input for a tag field.
*
* @return string The field input.
*
* @since 3.1
*/
protected function getInput()
{
// AJAX mode requires ajax-chosen
if (!$this->isNested())
{
// Get the field id
$id = isset($this->element['id']) ? $this->element['id'] : null;
$cssId = '#' . $this->getId($id, $this->element['name']);
// Load the ajax-chosen customised field
JHtml::_('tag.ajaxfield', $cssId, $this->allowCustom());
}
if (!is_array($this->value) && !empty($this->value))
{
if ($this->value instanceof JHelperTags)
{
if (empty($this->value->tags))
{
$this->value = array();
}
else
{
$this->value = $this->value->tags;
}
}
// String in format 2,5,4
if (is_string($this->value))
{
$this->value = explode(',', $this->value);
}
}
$input = parent::getInput();
return $input;
}
/**
* Method to get a list of tags
*
* @return array The field option objects.
*
* @since 3.1
*/
protected function getOptions()
{
$published = $this->element['published']? $this->element['published'] : array(0,1);
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select('a.id AS value, a.path, a.title AS text, a.level, a.published')
->from('#__tags AS a')
->join('LEFT', $db->quoteName('#__tags') . ' AS b ON a.lft > b.lft AND a.rgt < b.rgt');
// Ajax tag only loads assigned values
if (!$this->isNested())
{
// Only item assigned values
$values = (array) $this->value;
JArrayHelper::toInteger($values);
$query->where('a.id IN (' . implode(',', $values) . ')');
}
// Filter language
if (!empty($this->element['language']))
{
$query->where('a.language = ' . $db->quote($this->element['language']));
}
$query->where($db->quoteName('a.alias') . ' <> ' . $db->quote('root'));
// Filter on the published state
if (is_numeric($published))
{
$query->where('a.published = ' . (int) $published);
}
elseif (is_array($published))
{
JArrayHelper::toInteger($published);
$query->where('a.published IN (' . implode(',', $published) . ')');
}
$query->group('a.id, a.title, a.level, a.lft, a.rgt, a.parent_id, a.published, a.path')
->order('a.lft ASC');
// Get the options.
$db->setQuery($query);
try
{
$options = $db->loadObjectList();
}
catch (RuntimeException $e)
{
return false;
}
// Merge any additional options in the XML definition.
$options = array_merge(parent::getOptions(), $options);
// Prepare nested data
if ($this->isNested())
{
$this->prepareOptionsNested($options);
}
else
{
$options = JHelperTags::convertPathsToNames($options);
}
return $options;
}
/**
* Add "-" before nested tags, depending on level
*
* @param array &$options Array of tags
*
* @return array The field option objects.
*
* @since 3.1
*/
protected function prepareOptionsNested(&$options)
{
if ($options)
{
foreach ($options as &$option)
{
$repeat = (isset($option->level) && $option->level - 1 >= 0) ? $option->level - 1 : 0;
$option->text = str_repeat('- ', $repeat) . $option->text;
}
}
return $options;
}
/**
* Determine if the field has to be tagnested
*
* @return boolean
*
* @since 3.1
*/
public function isNested()
{
if (is_null($this->isNested))
{
// If mode="nested" || ( mode not set & config = nested )
if ((isset($this->element['mode']) && $this->element['mode'] == 'nested')
|| (!isset($this->element['mode']) && $this->comParams->get('tag_field_ajax_mode', 1) == 0))
{
$this->isNested = true;
}
}
return $this->isNested;
}
/**
* Determines if the field allows or denies custom values
*
* @return boolean
*/
public function allowCustom()
{
if (isset($this->element['custom']) && $this->element['custom'] == 'deny')
{
return false;
}
return true;
}
}

View File

@ -0,0 +1,103 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage Form
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
JFormHelper::loadFieldClass('groupedlist');
/**
* Form Field class for the Joomla CMS.
* Supports a select grouped list of template styles
*
* @package Joomla.Libraries
* @subpackage Form
* @since 1.6
*/
class JFormFieldTemplatestyle extends JFormFieldGroupedList
{
/**
* The form field type.
*
* @var string
* @since 1.6
*/
public $type = 'TemplateStyle';
/**
* Method to get the list of template style options
* grouped by template.
* Use the client attribute to specify a specific client.
* Use the template attribute to specify a specific template
*
* @return array The field option objects as a nested array in groups.
*
* @since 1.6
*/
protected function getGroups()
{
$groups = array();
$lang = JFactory::getLanguage();
// Get the client and client_id.
$clientName = $this->element['client'] ? (string) $this->element['client'] : 'site';
$client = JApplicationHelper::getClientInfo($clientName, true);
// Get the template.
$template = (string) $this->element['template'];
// Get the database object and a new query object.
$db = JFactory::getDbo();
$query = $db->getQuery(true);
// Build the query.
$query->select('s.id, s.title, e.name as name, s.template')
->from('#__template_styles as s')
->where('s.client_id = ' . (int) $client->id)
->order('template')
->order('title');
if ($template)
{
$query->where('s.template = ' . $db->quote($template));
}
$query->join('LEFT', '#__extensions as e on e.element=s.template')
->where('e.enabled=1')
->where($db->quoteName('e.type') . '=' . $db->quote('template'));
// Set the query and load the styles.
$db->setQuery($query);
$styles = $db->loadObjectList();
// Build the grouped list array.
if ($styles)
{
foreach ($styles as $style)
{
$template = $style->template;
$lang->load('tpl_' . $template . '.sys', $client->path, null, false, false)
|| $lang->load('tpl_' . $template . '.sys', $client->path . '/templates/' . $template, null, false, false)
|| $lang->load('tpl_' . $template . '.sys', $client->path, $lang->getDefault(), false, false)
|| $lang->load('tpl_' . $template . '.sys', $client->path . '/templates/' . $template, $lang->getDefault(), false, false);
$name = JText::_($style->name);
// Initialize the group if necessary.
if (!isset($groups[$name]))
{
$groups[$name] = array();
}
$groups[$name][] = JHtml::_('select.option', $style->id, $style->title);
}
}
// Merge any additional groups in the XML definition.
$groups = array_merge(parent::getGroups(), $groups);
return $groups;
}
}

View File

@ -0,0 +1,124 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage Form
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
/**
* Field to select a user id from a modal list.
*
* @package Joomla.Libraries
* @subpackage Form
* @since 1.6.0
*/
class JFormFieldUser extends JFormField
{
/**
* The form field type.
*
* @var string
* @since 1.6.0
*/
public $type = 'User';
/**
* Method to get the user field input markup.
*
* @return string The field input markup.
*
* @since 1.6.0
*/
protected function getInput()
{
$html = array();
$groups = $this->getGroups();
$excluded = $this->getExcluded();
$link = 'index.php?option=com_users&amp;view=users&amp;layout=modal&amp;tmpl=component&amp;field=' . $this->id
. (isset($groups) ? ('&amp;groups=' . base64_encode(json_encode($groups))) : '')
. (isset($excluded) ? ('&amp;excluded=' . base64_encode(json_encode($excluded))) : '');
// Initialize some field attributes.
$attr = $this->element['class'] ? ' class="' . (string) $this->element['class'] . '"' : '';
$attr .= $this->element['size'] ? ' size="' . (int) $this->element['size'] . '"' : '';
// Initialize JavaScript field attributes.
$onchange = (string) $this->element['onchange'];
// Load the modal behavior script.
JHtml::_('behavior.modal', 'a.modal_' . $this->id);
// Build the script.
$script = array();
$script[] = ' function jSelectUser_' . $this->id . '(id, title) {';
$script[] = ' var old_id = document.getElementById("' . $this->id . '_id").value;';
$script[] = ' if (old_id != id) {';
$script[] = ' document.getElementById("' . $this->id . '_id").value = id;';
$script[] = ' document.getElementById("' . $this->id . '_name").value = title;';
$script[] = ' ' . $onchange;
$script[] = ' }';
$script[] = ' SqueezeBox.close();';
$script[] = ' }';
// Add the script to the document head.
JFactory::getDocument()->addScriptDeclaration(implode("\n", $script));
// Load the current username if available.
$table = JTable::getInstance('user');
if ($this->value)
{
$table->load($this->value);
}
else
{
$table->username = JText::_('JLIB_FORM_SELECT_USER');
}
// Create a dummy text field with the user name.
$html[] = '<div class="input-append">';
$html[] = ' <input class="input-medium" type="text" id="' . $this->id . '_name" value="' . htmlspecialchars($table->name, ENT_COMPAT, 'UTF-8') . '"'
. ' disabled="disabled"' . $attr . ' />';
// Create the user select button.
if ($this->element['readonly'] != 'true')
{
$html[] = ' <a class="btn btn-primary modal_' . $this->id . '" title="' . JText::_('JLIB_FORM_CHANGE_USER') . '" href="' . $link . '"'
. ' rel="{handler: \'iframe\', size: {x: 800, y: 500}}">';
$html[] = '<i class="icon-user"></i></a>';
}
$html[] = '</div>';
// Create the real field, hidden, that stored the user id.
$html[] = '<input type="hidden" id="' . $this->id . '_id" name="' . $this->name . '" value="' . (int) $this->value . '" />';
return implode("\n", $html);
}
/**
* Method to get the filtering groups (null means no filtering)
*
* @return mixed array of filtering groups or null.
*
* @since 1.6.0
*/
protected function getGroups()
{
return null;
}
/**
* Method to get the users to exclude from the list of users
*
* @return mixed Array of users to exclude or null to to not exclude them
*
* @since 1.6.0
*/
protected function getExcluded()
{
return null;
}
}

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1,67 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage Form
*
* @copyright Copyright (C) 2005 - 2010 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('JPATH_PLATFORM') or die;
/**
* Form Rule class for the Joomla Framework.
*
* @package Joomla.Libraries
* @subpackage Form
* @since 2.5
*/
class JFormRuleCaptcha extends JFormRule
{
/**
* Method to test if the Captcha is correct.
*
* @param SimpleXMLElement $element The SimpleXMLElement object representing the <field /> tag for the form field object.
* @param mixed $value The form field value to validate.
* @param string $group The field name group control value. This acts as as an array container for the field.
* For example if the field has name="foo" and the group value is set to "bar" then the
* full field name would end up being "bar[foo]".
* @param JRegistry $input An optional JRegistry object with the entire data set to validate against the entire form.
* @param JForm $form The form object for which the field is being tested.
*
* @return boolean True if the value is valid, false otherwise.
*
* @since 2.5
*/
public function test(SimpleXMLElement $element, $value, $group = null, JRegistry $input = null, JForm $form = null)
{
$plugin = $element['plugin'] ?: JFactory::getApplication()->getParams()->get('captcha', JFactory::getConfig()->get('captcha', 0));
$namespace = $element['namespace'] ?: $form->getName();
// Use 0 for none
if ($plugin === 0 || $plugin === '0')
{
return true;
}
else
{
$captcha = JCaptcha::getInstance($plugin, array('namespace' => (string) $namespace));
}
// Test the value.
if (!$captcha->checkAnswer($value))
{
$error = $captcha->getError();
if ($error instanceof Exception)
{
return $error;
}
else
{
return new JException($error);
}
}
return true;
}
}

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1,68 @@
<?php
/**
* @package Joomla.Platform
* @subpackage Form
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
/**
* Form Rule class for the Joomla Platform.
*
* @package Joomla.Platform
* @subpackage Form
* @since 11.1
*/
class JFormRuleNotequals extends JFormRule
{
/**
* Method to test if two values are not equal. To use this rule, the form
* XML needs a validate attribute of equals and a field attribute
* that is equal to the field to test against.
*
* @param SimpleXMLElement $element The SimpleXMLElement object representing the <field /> tag for the form field object.
* @param mixed $value The form field value to validate.
* @param string $group The field name group control value. This acts as as an array container for the field.
* For example if the field has name="foo" and the group value is set to "bar" then the
* full field name would end up being "bar[foo]".
* @param JRegistry $input An optional JRegistry object with the entire data set to validate against the entire form.
* @param JForm $form The form object for which the field is being tested.
*
* @return boolean True if the value is valid, false otherwise.
*
* @since 11.1
* @throws InvalidArgumentException
* @throws UnexpectedValueException
*/
public function test(SimpleXMLElement $element, $value, $group = null, JRegistry $input = null, JForm $form = null)
{
$field = (string) $element['field'];
// Check that a validation field is set.
if (!$field)
{
throw new UnexpectedValueException(sprintf('$field empty in %s::test', get_class($this)));
}
if (is_null($form))
{
throw new InvalidArgumentException(sprintf('The value for $form must not be null in %s', get_class($this)));
}
if (is_null($input))
{
throw new InvalidArgumentException(sprintf('The value for $input must not be null in %s', get_class($this)));
}
// Test the two values against each other.
if ($value != $input->get($field))
{
return true;
}
return false;
}
}

View File

@ -0,0 +1,178 @@
<?php
/**
* @package Joomla.Platform
* @subpackage Form
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
/**
* Form Rule class for the Joomla Platform.
*
* @package Joomla.Libraries
* @subpackage Form
* @since 3.1.2
*/
class JFormRulePassword extends JFormRule
{
/**
* Method to test if two values are not equal. To use this rule, the form
* XML needs a validate attribute of equals and a field attribute
* that is equal to the field to test against.
*
* @param SimpleXMLElement $element The SimpleXMLElement object representing the <field /> tag for the form field object.
* @param mixed $value The form field value to validate.
* @param string $group The field name group control value. This acts as as an array container for the field.
* For example if the field has name="foo" and the group value is set to "bar" then the
* full field name would end up being "bar[foo]".
* @param JRegistry $input An optional JRegistry object with the entire data set to validate against the entire form.
* @param JForm $form The form object for which the field is being tested.
*
* @return boolean True if the value is valid, false otherwise.
*
* @since 3.1.2
* @throws InvalidArgumentException
* @throws UnexpectedValueException
*/
public function test(SimpleXMLElement $element, $value, $group = null, JRegistry $input = null, JForm $form = null)
{
$field = (string) $element['field'];
$meter = isset($this->element['strengthmeter']) ? ' meter="0"' : '1';
$threshold = isset($this->element['threshold']) ? (int) $this->element['threshold'] : 66;
$minimumLength = isset($this->element['minimum_length']) ? (int) $this->element['minimum_length'] : 4;
$minimumIntegers = isset($this->element['minimum_integers']) ? (int) $this->element['minimum_integers'] : 0;
$minimumSymbols = isset($this->element['minimum_symbols']) ? (int) $this->element['minimum_symbols'] : 0;
$minimumUppercase = isset($this->element['minimum_uppercase']) ? (int) $this->element['minimum_uppercase'] : 0;
// If we have parameters from com_users, use those instead.
// Some of these may be empty for legacy reasons.
$params = JComponentHelper::getParams('com_users');
if (!empty($params))
{
$minimumLengthp = $params->get('minimum_length');
$minimumIntegersp = $params->get('minimum_integers');
$minimumSymbolsp = $params->get('minimum_symbols');
$minimumUppercasep = $params->get('minimum_uppercase');
$meterp = $params->get('meter');
$thresholdp = $params->get('threshold');
empty($minimumLengthp) ? : $minimumLength = (int) $minimumLengthp;
empty($minimumIntegersp) ? : $minimumIntegers = (int) $minimumIntegersp;
empty($minimumSymbolsp) ? : $minimumSymbols = (int) $minimumSymbolsp;
empty($minimumUppercasep) ? : $minimumUppercase = (int) $minimumUppercasep;
empty($meterp) ? : $meter = $meterp;
empty($thresholdp) ? : $threshold = $thresholdp;
}
// If the field is empty and not required, the field is valid.
$required = ((string) $element['required'] == 'true' || (string) $element['required'] == 'required');
if (!$required && empty($value))
{
return true;
}
$valueLength = strlen($value);
// We set a maximum length to prevent abuse since it is unfiltered.
if ($valueLength > 99)
{
JFactory::getApplication()->enqueueMessage(
JText::_('COM_USERS_MSG_PASSWORD_TOO_LONG'),
'warning'
);
}
// We don't allow white space inside passwords
$valueTrim = trim($value);
// Set a variable to check if any errors are made in password
$validPassword = true;
if (strlen($valueTrim) != $valueLength)
{
JFactory::getApplication()->enqueueMessage(
JText::_('COM_USERS_MSG_SPACES_IN_PASSWORD'),
'warning'
);
$validPassword = false;
}
// Minimum number of integers required
if (!empty($minimumIntegers))
{
$nInts = preg_match_all('/[0-9]/', $value, $imatch);
if ($nInts < $minimumIntegers)
{
JFactory::getApplication()->enqueueMessage(
JText::plural('COM_USERS_MSG_NOT_ENOUGH_INTEGERS_N', $minimumIntegers),
'warning'
);
$validPassword = false;
}
}
// Minimum number of symbols required
if (!empty($minimumSymbols))
{
$nsymbols = preg_match_all('[\W]', $value, $smatch);
if ($nsymbols < $minimumSymbols)
{
JFactory::getApplication()->enqueueMessage(
JText::plural('COM_USERS_MSG_NOT_ENOUGH_SYMBOLS_N', $minimumSymbols),
'warning'
);
$validPassword = false;
}
}
// Minimum number of upper case ASII characters required
if (!empty($minimumUppercase))
{
$nUppercase = preg_match_all("/[A-Z]/", $value, $umatch);
if ($nUppercase < $minimumUppercase)
{
JFactory::getApplication()->enqueueMessage(
JText::plural('COM_USERS_MSG_NOT_ENOUGH_UPPERCASE_LETTERS_N', $minimumUppercase),
'warning'
);
$validPassword = false;
}
}
// Minimum length option
if (!empty($minimumLength))
{
if (strlen((string) $value) < $minimumLength)
{
JFactory::getApplication()->enqueueMessage(
JText::plural('COM_USERS_MSG_PASSWORD_TOO_SHORT_N', $minimumLength),
'warning'
);
$validPassword = false;
}
}
// If valid has violated any rules above return false.
if (!$validPassword)
{
return false;
}
return true;
}
}

207
libraries/cms/help/help.php Normal file
View File

@ -0,0 +1,207 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage Help
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
/**
* Help system class
*
* @package Joomla.Libraries
* @subpackage Help
* @since 1.5
*/
class JHelp
{
/**
* Create a URL for a given help key reference
*
* @param string $ref The name of the help screen (its key reference)
* @param boolean $useComponent Use the help file in the component directory
* @param string $override Use this URL instead of any other
* @param string $component Name of component (or null for current component)
*
* @return string
*
* @since 1.5
*/
public static function createURL($ref, $useComponent = false, $override = null, $component = null)
{
$local = false;
$app = JFactory::getApplication();
if (is_null($component))
{
$component = JApplicationHelper::getComponentName();
}
// Determine the location of the help file. At this stage the URL
// can contain substitution codes that will be replaced later.
if ($override)
{
$url = $override;
}
else
{
// Get the user help URL.
$user = JFactory::getUser();
$url = $user->getParam('helpsite');
// If user hasn't specified a help URL, then get the global one.
if ($url == '')
{
$url = $app->getCfg('helpurl');
}
// Component help URL overrides user and global.
if ($useComponent)
{
// Look for help URL in component parameters.
$params = JComponentHelper::getParams($component);
$url = $params->get('helpURL');
if ($url == '')
{
$local = true;
$url = 'components/{component}/help/{language}/{keyref}';
}
}
// Set up a local help URL.
if (!$url)
{
$local = true;
$url = 'help/{language}/{keyref}';
}
}
// If the URL is local then make sure we have a valid file extension on the URL.
if ($local)
{
if (!preg_match('#\.html$|\.xml$#i', $ref))
{
$url .= '.html';
}
}
/*
* Replace substitution codes in the URL.
*/
$lang = JFactory::getLanguage();
$version = new JVersion;
$jver = explode('.', $version->getShortVersion());
$jlang = explode('-', $lang->getTag());
$debug = $lang->setDebug(false);
$keyref = JText::_($ref);
$lang->setDebug($debug);
// Replace substitution codes in help URL.
$search = array(
// Application name (eg. 'Administrator')
'{app}',
// Component name (eg. 'com_content')
'{component}',
// Help screen key reference
'{keyref}',
// Full language code (eg. 'en-GB')
'{language}',
// Short language code (eg. 'en')
'{langcode}',
// Region code (eg. 'GB')
'{langregion}',
// Joomla major version number
'{major}',
// Joomla minor version number
'{minor}',
// Joomla maintenance version number
'{maintenance}'
);
$replace = array(
// {app}
$app->getName(),
// {component}
$component,
// {keyref}
$keyref,
// {language}
$lang->getTag(),
// {langcode}
$jlang[0],
// {langregion}
$jlang[1],
// {major}
$jver[0],
// {minor}
$jver[1],
// {maintenance}
$jver[2]
);
// If the help file is local then check it exists.
// If it doesn't then fallback to English.
if ($local)
{
$try = str_replace($search, $replace, $url);
if (!is_file(JPATH_BASE . '/' . $try))
{
$replace[3] = 'en-GB';
$replace[4] = 'en';
$replace[5] = 'GB';
}
}
$url = str_replace($search, $replace, $url);
return $url;
}
/**
* Builds a list of the help sites which can be used in a select option.
*
* @param string $pathToXml Path to an XML file.
*
* @return array An array of arrays (text, value, selected).
*
* @since 1.5
*/
public static function createSiteList($pathToXml)
{
$list = array();
$xml = false;
if (!empty($pathToXml))
{
$xml = simplexml_load_file($pathToXml);
}
if (!$xml)
{
$option['text'] = 'English (GB) help.joomla.org';
$option['value'] = 'http://help.joomla.org';
$list[] = $option;
}
else
{
$option = array();
foreach ($xml->sites->site as $site)
{
$option['text'] = (string) $site;
$option['value'] = (string) $site->attributes()->url;
$list[] = $option;
}
}
return $list;
}
}

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1,139 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage Helper
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* Helper for standard content style extensions.
*
* @package Joomla.Libraries
* @subpackage Helper
* @since 3.1
*/
class JHelperContent
{
/**
* Configure the Linkbar. Must be implemented by each extension.
*
* @param string $vName The name of the active view.
*
* @return void
*
* @since 3.1
*/
public static function addSubmenu($vName)
{
}
/**
* Gets a list of the actions that can be performed.
*
* @param integer $categoryId The category ID.
* @param integer $id The item ID.
* @param string $assetName The asset name
*
* @return JObject
*
* @since 3.1
*/
public static function getActions($categoryId = 0, $id = 0, $assetName = '')
{
// Reverted a change for version 2.5.6
$user = JFactory::getUser();
$result = new JObject;
$actions = array(
'core.admin', 'core.manage', 'core.create', 'core.edit', 'core.edit.own', 'core.edit.state', 'core.delete'
);
foreach ($actions as $action)
{
$result->set($action, $user->authorise($action, $assetName));
}
return $result;
}
/**
* Gets the current language
*
* @param boolean $detectBrowser Flag indicating whether to use the browser language as a fallback.
*
* @return string The language string
*
* @since 3.1
*/
public static function getCurrentLanguage($detectBrowser = true)
{
$app = JFactory::getApplication();
$langCode = $app->input->cookie->getString(JApplication::getHash('language'));
// No cookie - let's try to detect browser language or use site default
if (!$langCode)
{
if ($detectBrowser)
{
$langCode = JLanguageHelper::detectLanguage();
}
else
{
$langCode = JComponentHelper::getParams('com_languages')->get('site', 'en-GB');
}
}
return $langCode;
}
/**
* Gets the associated language ID
*
* @param string $langCode The language code to look up
*
* @return integer The language ID
*
* @since 3.1
*/
public static function getLanguageId($langCode)
{
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select('lang_id')
->from('#__languages')
->where($db->quoteName('lang_code') . ' = ' . $db->quote($langCode));
$db->setQuery($query);
$id = $db->loadResult();
return $id;
}
/**
* Gets a row of data from a table
*
* @param JTable $table JTable instance for a row.
*
* @return array Associative array of all columns and values for a row in a table.
*
* @since 3.1
*/
public function getRowData($table)
{
$fields = $table->getFields();
$data = array();
foreach ($fields as &$field)
{
$columnName = $field->Field;
$value = $table->$columnName;
$data[$columnName] = $value;
}
return $data;
}
}

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1,220 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage CMS
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* Route Helper
*
* A class providing basic routing for urls that are for content types found in
* the #__content_types table and rows found in the #__ucm_content table.
*
* @package Joomla.Libraries
* @subpackage CMS
* @since 3.1
*/
class JHelperRoute
{
/**
* @var array Holds the reverse lookup
* @since 3.1
*/
protected static $lookup;
/**
* @var string Option for the extension (such as com_content)
* @since 3.1
*/
protected $extension;
/**
* @var string Value of the primary key in the content type table
* @since 3.1
*/
protected $id;
/**
* @var string Name of the view for the url
* @since 3.1
*/
protected $view;
/**
* A method to get the route for a specific item
*
* @param integer $id Value of the primary key for the item in its content table
* @param string $typealias The type_alias for the item being routed. Of the form extension.view.
* @param string $link The link to be routed
* @param string $language The language of the content for multilingual sites
* @param integer $catid Optional category id
*
* @return string The route of the item
*
* @since 3.1
*/
public function getRoute($id, $typealias, $link = '', $language = null, $catid = null)
{
$typeExploded = explode('.', $typealias);
$this->view = $typeExploded[1];
$this->extension = $typeExploded[0];
$name = ucfirst(substr_replace($this->extension, '', 0, 4));
if (isset($this->view))
{
$needles = array(
$this->view => array((int) $id)
);
}
if (empty($link))
{
// Create the link
$link = 'index.php?option=' . $this->extension . '&view=' . $this->view . '&id=' . $id;
}
if ($catid > 1)
{
$categories = JCategories::getInstance($name);
if ($categories)
{
$category = $categories->get((int) $catid);
if ($category)
{
$needles['category'] = array_reverse($category->getPath());
$needles['categories'] = $needles['category'];
$link .= '&catid=' . $catid;
}
}
}
// Deal with languages only if needed
if (!empty($language) && $language != '*' && JLanguageMultilang::isEnabled())
{
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select('a.sef AS sef')
->select('a.lang_code AS lang_code')
->from('#__languages AS a');
$db->setQuery($query);
$langs = $db->loadObjectList();
foreach ($langs as $lang)
{
if ($language == $lang->lang_code)
{
$link .= '&lang=' . $lang->sef;
$needles['language'] = $language;
}
}
}
if ($item = self::findItem($needles))
{
$link .= '&Itemid=' . $item;
}
elseif ($item = self::findItem())
{
$link .= '&Itemid=' . $item;
}
return $link;
}
/**
* Method to find the item in the menu structure
*
* @param array $needles Array of lookup values
*
* @return mixed
*
* @since 3.1
*/
protected function findItem($needles = array())
{
$app = JFactory::getApplication();
$menus = $app->getMenu('site');
$language = isset($needles['language']) ? $needles['language'] : '*';
// Prepare the reverse lookup array.
if (!isset(self::$lookup[$language]))
{
self::$lookup[$language] = array();
$component = JComponentHelper::getComponent($this->extension);
$attributes = array('component_id');
$values = array($component->id);
if ($language != '*')
{
$attributes[] = 'language';
$values[] = array($needles['language'], '*');
}
$items = $menus->getItems($attributes, $values);
foreach ($items as $item)
{
if (isset($item->query) && isset($item->query['view']))
{
$view = $item->query['view'];
if (!isset(self::$lookup[$language][$view]))
{
self::$lookup[$language][$view] = array();
}
if (isset($item->query['id']))
{
if (is_array($item->query['id']))
{
$item->query['id'] = $item->query['id'][0];
}
/*
* Here it will become a bit tricky
* $language != * can override existing entries
* $language == * cannot override existing entries
*/
if (!isset(self::$lookup[$language][$view][$item->query['id']]) || $item->language != '*')
{
self::$lookup[$language][$view][$item->query['id']] = $item->id;
}
}
}
}
}
if ($needles)
{
foreach ($needles as $view => $ids)
{
if (isset(self::$lookup[$language][$view]))
{
foreach ($ids as $id)
{
if (isset(self::$lookup[$language][$view][(int) $id]))
{
return self::$lookup[$language][$view][(int) $id];
}
}
}
}
}
$active = $menus->getActive();
if ($active && $active->component == $this->extension && ($active->language == '*' || !JLanguageMultilang::isEnabled()))
{
return $active->id;
}
// If not found, return language specific home link
$default = $menus->getDefault($language);
return !empty($default->id) ? $default->id : null;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,294 @@
<?php
/**
* @package Joomla.Platform
* @subpackage HTML
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
/**
* Extended Utility class for all HTML drawing classes.
*
* @package Joomla.Platform
* @subpackage HTML
* @since 1.6
*/
abstract class JHtmlAccess
{
/**
* A cached array of the asset groups
*
* @var array
* @since 1.6
*/
protected static $asset_groups = null;
/**
* Displays a list of the available access view levels
*
* @param string $name The form field name.
* @param string $selected The name of the selected section.
* @param string $attribs Additional attributes to add to the select field.
* @param mixed $params True to add "All Sections" option or and array of options
* @param string $id The form field id
*
* @return string The required HTML for the SELECT tag.
*
* @see JFormFieldAccessLevel
* @since 1.6
*/
public static function level($name, $selected, $attribs = '', $params = true, $id = false)
{
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select('a.id AS value, a.title AS text')
->from('#__viewlevels AS a')
->group('a.id, a.title, a.ordering')
->order('a.ordering ASC')
->order($db->quoteName('title') . ' ASC');
// Get the options.
$db->setQuery($query);
$options = $db->loadObjectList();
// If params is an array, push these options to the array
if (is_array($params))
{
$options = array_merge($params, $options);
}
// If all levels is allowed, push it into the array.
elseif ($params)
{
array_unshift($options, JHtml::_('select.option', '', JText::_('JOPTION_ACCESS_SHOW_ALL_LEVELS')));
}
return JHtml::_(
'select.genericlist',
$options,
$name,
array(
'list.attr' => $attribs,
'list.select' => $selected,
'id' => $id
)
);
}
/**
* Displays a list of the available user groups.
*
* @param string $name The form field name.
* @param string $selected The name of the selected section.
* @param string $attribs Additional attributes to add to the select field.
* @param boolean $allowAll True to add "All Groups" option.
*
* @return string The required HTML for the SELECT tag.
*
* @see JFormFieldUsergroup
* @since 1.6
*/
public static function usergroup($name, $selected, $attribs = '', $allowAll = true)
{
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select('a.id AS value, a.title AS text, COUNT(DISTINCT b.id) AS level')
->from($db->quoteName('#__usergroups') . ' AS a')
->join('LEFT', $db->quoteName('#__usergroups') . ' AS b ON a.lft > b.lft AND a.rgt < b.rgt')
->group('a.id, a.title, a.lft, a.rgt')
->order('a.lft ASC');
$db->setQuery($query);
$options = $db->loadObjectList();
for ($i = 0, $n = count($options); $i < $n; $i++)
{
$options[$i]->text = str_repeat('- ', $options[$i]->level) . $options[$i]->text;
}
// If all usergroups is allowed, push it into the array.
if ($allowAll)
{
array_unshift($options, JHtml::_('select.option', '', JText::_('JOPTION_ACCESS_SHOW_ALL_GROUPS')));
}
return JHtml::_('select.genericlist', $options, $name, array('list.attr' => $attribs, 'list.select' => $selected));
}
/**
* Returns a UL list of user groups with check boxes
*
* @param string $name The name of the checkbox controls array
* @param array $selected An array of the checked boxes
* @param boolean $checkSuperAdmin If false only super admins can add to super admin groups
*
* @return string
*
* @since 1.6
*/
public static function usergroups($name, $selected, $checkSuperAdmin = false)
{
static $count;
$count++;
$isSuperAdmin = JFactory::getUser()->authorise('core.admin');
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select('a.*, COUNT(DISTINCT b.id) AS level')
->from($db->quoteName('#__usergroups') . ' AS a')
->join('LEFT', $db->quoteName('#__usergroups') . ' AS b ON a.lft > b.lft AND a.rgt < b.rgt')
->group('a.id, a.title, a.lft, a.rgt, a.parent_id')
->order('a.lft ASC');
$db->setQuery($query);
$groups = $db->loadObjectList();
$html = array();
for ($i = 0, $n = count($groups); $i < $n; $i++)
{
$item = &$groups[$i];
// If checkSuperAdmin is true, only add item if the user is superadmin or the group is not super admin
if ((!$checkSuperAdmin) || $isSuperAdmin || (!JAccess::checkGroup($item->id, 'core.admin')))
{
// Setup the variable attributes.
$eid = $count . 'group_' . $item->id;
// Don't call in_array unless something is selected
$checked = '';
if ($selected)
{
$checked = in_array($item->id, $selected) ? ' checked="checked"' : '';
}
$rel = ($item->parent_id > 0) ? ' rel="' . $count . 'group_' . $item->parent_id . '"' : '';
// Build the HTML for the item.
$html[] = ' <div class="control-group">';
$html[] = ' <div class="controls">';
$html[] = ' <label class="checkbox" for="' . $eid . '">';
$html[] = ' <input type="checkbox" name="' . $name . '[]" value="' . $item->id . '" id="' . $eid . '"';
$html[] = ' ' . $checked . $rel . ' />';
$html[] = ' ' . str_repeat('<span class="gi">|&mdash;</span>', $item->level) . $item->title;
$html[] = ' </label>';
$html[] = ' </div>';
$html[] = ' </div>';
}
}
return implode("\n", $html);
}
/**
* Returns a UL list of actions with check boxes
*
* @param string $name The name of the checkbox controls array
* @param array $selected An array of the checked boxes
* @param string $component The component the permissions apply to
* @param string $section The section (within a component) the permissions apply to
*
* @return string
*
* @see JAccess
* @since 1.6
*/
public static function actions($name, $selected, $component, $section = 'global')
{
static $count;
$count++;
$actions = JAccess::getActionsFromFile(
JPATH_ADMINISTRATOR . '/components/' . $component . '/access.xml',
"/access/section[@name='" . $section . "']/"
);
$html = array();
$html[] = '<ul class="checklist access-actions">';
for ($i = 0, $n = count($actions); $i < $n; $i++)
{
$item = &$actions[$i];
// Setup the variable attributes.
$eid = $count . 'action_' . $item->id;
$checked = in_array($item->id, $selected) ? ' checked="checked"' : '';
// Build the HTML for the item.
$html[] = ' <li>';
$html[] = ' <input type="checkbox" name="' . $name . '[]" value="' . $item->id . '" id="' . $eid . '"';
$html[] = ' ' . $checked . ' />';
$html[] = ' <label for="' . $eid . '">';
$html[] = ' ' . JText::_($item->title);
$html[] = ' </label>';
$html[] = ' </li>';
}
$html[] = '</ul>';
return implode("\n", $html);
}
/**
* Gets a list of the asset groups as an array of JHtml compatible options.
*
* @return mixed An array or false if an error occurs
*
* @since 1.6
*/
public static function assetgroups()
{
if (empty(static::$asset_groups))
{
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select('a.id AS value, a.title AS text')
->from($db->quoteName('#__viewlevels') . ' AS a')
->group('a.id, a.title, a.ordering')
->order('a.ordering ASC');
$db->setQuery($query);
static::$asset_groups = $db->loadObjectList();
}
return static::$asset_groups;
}
/**
* Displays a Select list of the available asset groups
*
* @param string $name The name of the select element
* @param mixed $selected The selected asset group id
* @param string $attribs Optional attributes for the select field
* @param array $config An array of options for the control
*
* @return mixed An HTML string or null if an error occurs
*
* @since 1.6
*/
public static function assetgrouplist($name, $selected, $attribs = null, $config = array())
{
static $count;
$options = static::assetgroups();
if (isset($config['title']))
{
array_unshift($options, JHtml::_('select.option', '', $config['title']));
}
return JHtml::_(
'select.genericlist',
$options,
$name,
array(
'id' => isset($config['id']) ? $config['id'] : 'assetgroups_' . (++$count),
'list.attr' => (is_null($attribs) ? 'class="inputbox" size="3"' : $attribs),
'list.select' => (int) $selected
)
);
}
}

View File

@ -0,0 +1,159 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage HTML
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_BASE') or die;
/**
* Extended Utility class for batch processing widgets.
*
* @package Joomla.Libraries
* @subpackage HTML
* @since 1.7
*/
abstract class JHtmlBatch
{
/**
* Display a batch widget for the access level selector.
*
* @return string The necessary HTML for the widget.
*
* @since 1.7
*/
public static function access()
{
JHtml::_('bootstrap.tooltip');
// Create the batch selector to change an access level on a selection list.
return
'<label id="batch-access-lbl" for="batch-access" class="hasToolip"'
. 'title="' . JHtml::tooltipText('JLIB_HTML_BATCH_ACCESS_LABEL', 'JLIB_HTML_BATCH_ACCESS_LABEL_DESC') . '">'
. JText::_('JLIB_HTML_BATCH_ACCESS_LABEL')
. '</label>'
. JHtml::_(
'access.assetgrouplist',
'batch[assetgroup_id]', '',
'class="inputbox"',
array(
'title' => JText::_('JLIB_HTML_BATCH_NOCHANGE'),
'id' => 'batch-access'
)
);
return implode("\n", $lines);
}
/**
* Displays a batch widget for moving or copying items.
*
* @param string $extension The extension that owns the category.
*
* @return string The necessary HTML for the widget.
*
* @since 1.7
*/
public static function item($extension)
{
// Create the copy/move options.
$options = array(
JHtml::_('select.option', 'c', JText::_('JLIB_HTML_BATCH_COPY')),
JHtml::_('select.option', 'm', JText::_('JLIB_HTML_BATCH_MOVE'))
);
// Create the batch selector to change select the category by which to move or copy.
return
'<label id="batch-choose-action-lbl" for="batch-choose-action">' . JText::_('JLIB_HTML_BATCH_MENU_LABEL') . '</label>'
. '<div id="batch-choose-action" class="control-group">'
. '<select name="batch[category_id]" class="inputbox" id="batch-category-id">'
. '<option value="">' . JText::_('JSELECT') . '</option>'
. JHtml::_('select.options', JHtml::_('category.options', $extension))
. '</select>'
. '</div>'
. '<div id="batch-move-copy" class="control-group radio">'
. JHtml::_('select.radiolist', $options, 'batch[move_copy]', '', 'value', 'text', 'm')
. '</div><hr />';
}
/**
* Display a batch widget for the language selector.
*
* @return string The necessary HTML for the widget.
*
* @since 2.5
*/
public static function language()
{
JHtml::_('bootstrap.tooltip');
// Create the batch selector to change the language on a selection list.
return
'<label id="batch-language-lbl" for="batch-language-id" class="hasToolip"'
. ' title="' . JHtml::tooltipText('JLIB_HTML_BATCH_LANGUAGE_LABEL', 'JLIB_HTML_BATCH_LANGUAGE_LABEL_DESC') . '">'
. JText::_('JLIB_HTML_BATCH_LANGUAGE_LABEL')
. '</label>'
. '<select name="batch[language_id]" class="inputbox" id="batch-language-id">'
. '<option value="">' . JText::_('JLIB_HTML_BATCH_LANGUAGE_NOCHANGE') . '</option>'
. JHtml::_('select.options', JHtml::_('contentlanguage.existing', true, true), 'value', 'text')
. '</select>';
}
/**
* Display a batch widget for the user selector.
*
* @param boolean $noUser Choose to display a "no user" option
*
* @return string The necessary HTML for the widget.
*
* @since 2.5
*/
public static function user($noUser = true)
{
JHtml::_('bootstrap.tooltip');
$optionNo = '';
if ($noUser)
{
$optionNo = '<option value="0">' . JText::_('JLIB_HTML_BATCH_USER_NOUSER') . '</option>';
}
// Create the batch selector to select a user on a selection list.
return
'<label id="batch-user-lbl" for="batch-user" class="hasTooltip"'
. ' title="' . JHtml::tooltipText('JLIB_HTML_BATCH_USER_LABEL', 'JLIB_HTML_BATCH_USER_LABEL_DESC') . '">'
. JText::_('JLIB_HTML_BATCH_USER_LABEL')
. '</label>'
. '<select name="batch[user_id]" class="inputbox" id="batch-user-id">'
. '<option value="">' . JText::_('JLIB_HTML_BATCH_USER_NOCHANGE') . '</option>'
. $optionNo
. JHtml::_('select.options', JHtml::_('user.userlist'), 'value', 'text')
. '</select>';
}
/**
* Display a batch widget for the tag selector.
*
* @return string The necessary HTML for the widget.
*
* @since 3.1
*/
public static function tag()
{
JHtml::_('bootstrap.tooltip');
// Create the batch selector to tag items on a selection list.
return
'<label id="batch-tag-lbl" for="batch-tag-id" class="hasTooltip"'
. ' title="' . JHtml::tooltipText('JLIB_HTML_BATCH_TAG_LABEL', 'JLIB_HTML_BATCH_TAG_LABEL_DESC') . '">'
. JText::_('JLIB_HTML_BATCH_TAG_LABEL')
. '</label>'
. '<select name="batch[tag]" class="inputbox" id="batch-tag-id">'
. '<option value="">' . JText::_('JLIB_HTML_BATCH_TAG_NOCHANGE') . '</option>'
. JHtml::_('select.options', JHtml::_('tag.tags', array('filter.published' => array(1))), 'value', 'text')
. '</select>';
}
}

View File

@ -0,0 +1,781 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage HTML
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
/**
* Utility class for JavaScript behaviors
*
* @package Joomla.Libraries
* @subpackage HTML
* @since 1.5
*/
abstract class JHtmlBehavior
{
/**
* Array containing information for loaded files
*
* @var array
* @since 2.5
*/
protected static $loaded = array();
/**
* Method to load the MooTools framework into the document head
*
* If debugging mode is on an uncompressed version of MooTools is included for easier debugging.
*
* @param boolean $extras Flag to determine whether to load MooTools More in addition to Core
* @param mixed $debug Is debugging mode on? [optional]
*
* @return void
*
* @since 1.6
*/
public static function framework($extras = false, $debug = null)
{
$type = $extras ? 'more' : 'core';
// Only load once
if (!empty(static::$loaded[__METHOD__][$type]))
{
return;
}
// If no debugging value is set, use the configuration setting
if ($debug === null)
{
$config = JFactory::getConfig();
$debug = $config->get('debug');
}
if ($type != 'core' && empty(static::$loaded[__METHOD__]['core']))
{
static::framework(false, $debug);
}
JHtml::_('script', 'system/mootools-' . $type . '.js', false, true, false, false, $debug);
JHtml::_('script', 'system/core.js', false, true);
static::$loaded[__METHOD__][$type] = true;
return;
}
/**
* Add unobtrusive JavaScript support for image captions.
*
* @param string $selector The selector for which a caption behaviour is to be applied.
*
* @return void
*
* @since 1.5
*/
public static function caption($selector = 'img.caption')
{
// Only load once
if (isset(static::$loaded[__METHOD__][$selector]))
{
return;
}
// Include MooTools framework
static::framework();
JHtml::_('script', 'system/caption.js', true, true);
// Attach caption to document
JFactory::getDocument()->addScriptDeclaration(
"window.addEvent('load', function() {
new JCaption('" . $selector . "');
});"
);
// Set static array
static::$loaded[__METHOD__][$selector] = true;
}
/**
* Add unobtrusive JavaScript support for form validation.
*
* To enable form validation the form tag must have class="form-validate".
* Each field that needs to be validated needs to have class="validate".
* Additional handlers can be added to the handler for username, password,
* numeric and email. To use these add class="validate-email" and so on.
*
* @return void
*
* @since 1.5
*/
public static function formvalidation()
{
// Only load once
if (isset(static::$loaded[__METHOD__]))
{
return;
}
// Add validate.js language strings
JText::script('JLIB_FORM_FIELD_INVALID');
// Include MooTools More framework
static::framework('more');
JHtml::_('script', 'system/validate.js', true, true);
static::$loaded[__METHOD__] = true;
}
/**
* Add unobtrusive JavaScript support for submenu switcher support
*
* @return void
*
* @since 1.5
*/
public static function switcher()
{
// Only load once
if (isset(static::$loaded[__METHOD__]))
{
return;
}
// Include MooTools framework
static::framework();
JHtml::_('script', 'system/switcher.js', true, true);
$script = "
document.switcher = null;
window.addEvent('domready', function(){
toggler = document.id('submenu');
element = document.id('config-document');
if (element) {
document.switcher = new JSwitcher(toggler, element, {cookieName: toggler.getProperty('class')});
}
});";
JFactory::getDocument()->addScriptDeclaration($script);
static::$loaded[__METHOD__] = true;
}
/**
* Add unobtrusive JavaScript support for a combobox effect.
*
* Note that this control is only reliable in absolutely positioned elements.
* Avoid using a combobox in a slider or dynamic pane.
*
* @return void
*
* @since 1.5
*/
public static function combobox()
{
if (isset(static::$loaded[__METHOD__]))
{
return;
}
// Include MooTools framework
static::framework();
JHtml::_('script', 'system/combobox.js', true, true);
static::$loaded[__METHOD__] = true;
}
/**
* Add unobtrusive JavaScript support for a hover tooltips.
*
* Add a title attribute to any element in the form
* title="title::text"
*
* Uses the core Tips class in MooTools.
*
* @param string $selector The class selector for the tooltip.
* @param array $params An array of options for the tooltip.
* Options for the tooltip can be:
* - maxTitleChars integer The maximum number of characters in the tooltip title (defaults to 50).
* - offsets object The distance of your tooltip from the mouse (defaults to {'x': 16, 'y': 16}).
* - showDelay integer The millisecond delay the show event is fired (defaults to 100).
* - hideDelay integer The millisecond delay the hide hide is fired (defaults to 100).
* - className string The className your tooltip container will get.
* - fixed boolean If set to true, the toolTip will not follow the mouse.
* - onShow function The default function for the show event, passes the tip element
* and the currently hovered element.
* - onHide function The default function for the hide event, passes the currently
* hovered element.
*
* @return void
*
* @since 1.5
*/
public static function tooltip($selector = '.hasTip', $params = array())
{
$sig = md5(serialize(array($selector, $params)));
if (isset(static::$loaded[__METHOD__][$sig]))
{
return;
}
// Include MooTools framework
static::framework(true);
// Setup options object
$opt['maxTitleChars'] = (isset($params['maxTitleChars']) && ($params['maxTitleChars'])) ? (int) $params['maxTitleChars'] : 50;
// Offsets needs an array in the format: array('x'=>20, 'y'=>30)
$opt['offset'] = (isset($params['offset']) && (is_array($params['offset']))) ? $params['offset'] : null;
$opt['showDelay'] = (isset($params['showDelay'])) ? (int) $params['showDelay'] : null;
$opt['hideDelay'] = (isset($params['hideDelay'])) ? (int) $params['hideDelay'] : null;
$opt['className'] = (isset($params['className'])) ? $params['className'] : null;
$opt['fixed'] = (isset($params['fixed']) && ($params['fixed'])) ? true : false;
$opt['onShow'] = (isset($params['onShow'])) ? '\\' . $params['onShow'] : null;
$opt['onHide'] = (isset($params['onHide'])) ? '\\' . $params['onHide'] : null;
$options = JHtml::getJSObject($opt);
// Attach tooltips to document
JFactory::getDocument()->addScriptDeclaration(
"window.addEvent('domready', function() {
$$('$selector').each(function(el) {
var title = el.get('title');
if (title) {
var parts = title.split('::', 2);
el.store('tip:title', parts[0]);
el.store('tip:text', parts[1]);
}
});
var JTooltips = new Tips($$('$selector'), $options);
});"
);
// Set static array
static::$loaded[__METHOD__][$sig] = true;
return;
}
/**
* Add unobtrusive JavaScript support for modal links.
*
* @param string $selector The selector for which a modal behaviour is to be applied.
* @param array $params An array of parameters for the modal behaviour.
* Options for the modal behaviour can be:
* - ajaxOptions
* - size
* - shadow
* - overlay
* - onOpen
* - onClose
* - onUpdate
* - onResize
* - onShow
* - onHide
*
* @return void
*
* @since 1.5
*/
public static function modal($selector = 'a.modal', $params = array())
{
$document = JFactory::getDocument();
// Load the necessary files if they haven't yet been loaded
if (!isset(static::$loaded[__METHOD__]))
{
// Include MooTools framework
static::framework(true);
// Load the JavaScript and css
JHtml::_('script', 'system/modal.js', true, true);
JHtml::_('stylesheet', 'system/modal.css', array(), true);
}
$sig = md5(serialize(array($selector, $params)));
if (isset(static::$loaded[__METHOD__][$sig]))
{
return;
}
// Setup options object
$opt['ajaxOptions'] = (isset($params['ajaxOptions']) && (is_array($params['ajaxOptions']))) ? $params['ajaxOptions'] : null;
$opt['handler'] = (isset($params['handler'])) ? $params['handler'] : null;
$opt['parseSecure'] = (isset($params['parseSecure'])) ? (bool) $params['parseSecure'] : null;
$opt['closable'] = (isset($params['closable'])) ? (bool) $params['closable'] : null;
$opt['closeBtn'] = (isset($params['closeBtn'])) ? (bool) $params['closeBtn'] : null;
$opt['iframePreload'] = (isset($params['iframePreload'])) ? (bool) $params['iframePreload'] : null;
$opt['iframeOptions'] = (isset($params['iframeOptions']) && (is_array($params['iframeOptions']))) ? $params['iframeOptions'] : null;
$opt['size'] = (isset($params['size']) && (is_array($params['size']))) ? $params['size'] : null;
$opt['shadow'] = (isset($params['shadow'])) ? $params['shadow'] : null;
$opt['overlay'] = (isset($params['overlay'])) ? $params['overlay'] : null;
$opt['onOpen'] = (isset($params['onOpen'])) ? $params['onOpen'] : null;
$opt['onClose'] = (isset($params['onClose'])) ? $params['onClose'] : null;
$opt['onUpdate'] = (isset($params['onUpdate'])) ? $params['onUpdate'] : null;
$opt['onResize'] = (isset($params['onResize'])) ? $params['onResize'] : null;
$opt['onMove'] = (isset($params['onMove'])) ? $params['onMove'] : null;
$opt['onShow'] = (isset($params['onShow'])) ? $params['onShow'] : null;
$opt['onHide'] = (isset($params['onHide'])) ? $params['onHide'] : null;
if (isset($params['fullScreen']) && (bool) $params['fullScreen'])
{
$opt['size'] = array('x' => '\\window.getSize().x-80', 'y' => '\\window.getSize().y-80');
}
$options = JHtml::getJSObject($opt);
// Attach modal behavior to document
$document
->addScriptDeclaration(
"
window.addEvent('domready', function() {
SqueezeBox.initialize(" . $options . ");
SqueezeBox.assign($$('" . $selector . "'), {
parse: 'rel'
});
});"
);
// Set static array
static::$loaded[__METHOD__][$sig] = true;
return;
}
/**
* JavaScript behavior to allow shift select in grids
*
* @param string $id The id of the form for which a multiselect behaviour is to be applied.
*
* @return void
*
* @since 1.7
*/
public static function multiselect($id = 'adminForm')
{
// Only load once
if (isset(static::$loaded[__METHOD__][$id]))
{
return;
}
// Include MooTools framework
static::framework();
JHtml::_('script', 'system/multiselect.js', true, true);
// Attach multiselect to document
JFactory::getDocument()->addScriptDeclaration(
"window.addEvent('domready', function() {
new Joomla.JMultiSelect('" . $id . "');
});"
);
// Set static array
static::$loaded[__METHOD__][$id] = true;
return;
}
/**
* Add unobtrusive javascript support for a collapsible tree.
*
* @param string $id An index
* @param array $params An array of options.
* @param array $root The root node
*
* @return void
*
* @since 1.5
*/
public static function tree($id, $params = array(), $root = array())
{
// Include MooTools framework
static::framework();
JHtml::_('script', 'system/mootree.js', true, true, false, false);
JHtml::_('stylesheet', 'system/mootree.css', array(), true);
if (isset(static::$loaded[__METHOD__][$id]))
{
return;
}
// Setup options object
$opt['div'] = (array_key_exists('div', $params)) ? $params['div'] : $id . '_tree';
$opt['mode'] = (array_key_exists('mode', $params)) ? $params['mode'] : 'folders';
$opt['grid'] = (array_key_exists('grid', $params)) ? '\\' . $params['grid'] : true;
$opt['theme'] = (array_key_exists('theme', $params)) ? $params['theme'] : JHtml::_('image', 'system/mootree.gif', '', array(), true, true);
// Event handlers
$opt['onExpand'] = (array_key_exists('onExpand', $params)) ? '\\' . $params['onExpand'] : null;
$opt['onSelect'] = (array_key_exists('onSelect', $params)) ? '\\' . $params['onSelect'] : null;
$opt['onClick'] = (array_key_exists('onClick', $params)) ? '\\' . $params['onClick']
: '\\function(node){ window.open(node.data.url, node.data.target != null ? node.data.target : \'_self\'); }';
$options = JHtml::getJSObject($opt);
// Setup root node
$rt['text'] = (array_key_exists('text', $root)) ? $root['text'] : 'Root';
$rt['id'] = (array_key_exists('id', $root)) ? $root['id'] : null;
$rt['color'] = (array_key_exists('color', $root)) ? $root['color'] : null;
$rt['open'] = (array_key_exists('open', $root)) ? '\\' . $root['open'] : true;
$rt['icon'] = (array_key_exists('icon', $root)) ? $root['icon'] : null;
$rt['openicon'] = (array_key_exists('openicon', $root)) ? $root['openicon'] : null;
$rt['data'] = (array_key_exists('data', $root)) ? $root['data'] : null;
$rootNode = JHtml::getJSObject($rt);
$treeName = (array_key_exists('treeName', $params)) ? $params['treeName'] : '';
$js = ' window.addEvent(\'domready\', function(){
tree' . $treeName . ' = new MooTreeControl(' . $options . ',' . $rootNode . ');
tree' . $treeName . '.adopt(\'' . $id . '\');})';
// Attach tooltips to document
$document = JFactory::getDocument();
$document->addScriptDeclaration($js);
// Set static array
static::$loaded[__METHOD__][$id] = true;
return;
}
/**
* Add unobtrusive JavaScript support for a calendar control.
*
* @return void
*
* @since 1.5
*/
public static function calendar()
{
// Only load once
if (isset(static::$loaded[__METHOD__]))
{
return;
}
$document = JFactory::getDocument();
$tag = JFactory::getLanguage()->getTag();
JHtml::_('stylesheet', 'system/calendar-jos.css', array(' title' => JText::_('JLIB_HTML_BEHAVIOR_GREEN'), ' media' => 'all'), true);
JHtml::_('script', $tag . '/calendar.js', false, true);
JHtml::_('script', $tag . '/calendar-setup.js', false, true);
$translation = static::calendartranslation();
if ($translation)
{
$document->addScriptDeclaration($translation);
}
static::$loaded[__METHOD__] = true;
}
/**
* Add unobtrusive JavaScript support for a color picker.
*
* @return void
*
* @since 1.7
*/
public static function colorpicker()
{
// Only load once
if (isset(static::$loaded[__METHOD__]))
{
return;
}
// Include jQuery
JHtml::_('jquery.framework');
JHtml::_('script', 'jui/jquery.minicolors.min.js', false, true);
JHtml::_('stylesheet', 'jui/jquery.minicolors.css', false, true);
JFactory::getDocument()->addScriptDeclaration("
jQuery(document).ready(function (){
jQuery('.minicolors').each(function() {
jQuery(this).minicolors({
control: jQuery(this).attr('data-control') || 'hue',
position: jQuery(this).attr('data-position') || 'right',
theme: 'bootstrap'
});
});
});
"
);
static::$loaded[__METHOD__] = true;
}
/**
* Add unobtrusive JavaScript support for a simple color picker.
*
* @return void
*
* @since 3.1
*/
public static function simplecolorpicker()
{
// Only load once
if (isset(static::$loaded[__METHOD__]))
{
return;
}
// Include jQuery
JHtml::_('jquery.framework');
JHtml::_('script', 'jui/jquery.simplecolors.min.js', false, true);
JHtml::_('stylesheet', 'jui/jquery.simplecolors.css', false, true);
JFactory::getDocument()->addScriptDeclaration("
jQuery(document).ready(function (){
jQuery('select.simplecolors').simplecolors();
});
"
);
static::$loaded[__METHOD__] = true;
}
/**
* Keep session alive, for example, while editing or creating an article.
*
* @return void
*
* @since 1.5
*/
public static function keepalive()
{
// Only load once
if (isset(static::$loaded[__METHOD__]))
{
return;
}
// Include MooTools framework
static::framework();
$config = JFactory::getConfig();
$lifetime = ($config->get('lifetime') * 60000);
$refreshTime = ($lifetime <= 60000) ? 30000 : $lifetime - 60000;
// Refresh time is 1 minute less than the liftime assined in the configuration.php file.
// The longest refresh period is one hour to prevent integer overflow.
if ($refreshTime > 3600000 || $refreshTime <= 0)
{
$refreshTime = 3600000;
}
$document = JFactory::getDocument();
$script = '';
$script .= 'function keepAlive() {';
$script .= ' var myAjax = new Request({method: "get", url: "index.php"}).send();';
$script .= '}';
$script .= ' window.addEvent("domready", function()';
$script .= '{ keepAlive.periodical(' . $refreshTime . '); }';
$script .= ');';
$document->addScriptDeclaration($script);
static::$loaded[__METHOD__] = true;
return;
}
/**
* Highlight some words via Javascript.
*
* @param array $terms Array of words that should be highlighted.
* @param string $start ID of the element that marks the begin of the section in which words
* should be highlighted. Note this element will be removed from the DOM.
* @param string $end ID of the element that end this section.
* Note this element will be removed from the DOM.
* @param string $className Class name of the element highlights are wrapped in.
* @param string $tag Tag that will be used to wrap the highlighted words.
*
* @return void
*
* @since 2.5
*/
public static function highlighter(array $terms, $start = 'highlighter-start', $end = 'highlighter-end', $className = 'highlight', $tag = 'span')
{
$sig = md5(serialize(array($terms, $start, $end)));
if (isset(static::$loaded[__METHOD__][$sig]))
{
return;
}
JHtml::_('script', 'system/highlighter.js', true, true);
$terms = str_replace('"', '\"', $terms);
$document = JFactory::getDocument();
$document->addScriptDeclaration("
window.addEvent('domready', function () {
var start = document.id('" . $start . "');
var end = document.id('" . $end . "');
if (!start || !end || !Joomla.Highlighter) {
return true;
}
highlighter = new Joomla.Highlighter({
startElement: start,
endElement: end,
className: '" . $className . "',
onlyWords: false,
tag: '" . $tag . "'
}).highlight([\"" . implode('","', $terms) . "\"]);
start.dispose();
end.dispose();
});
");
static::$loaded[__METHOD__][$sig] = true;
return;
}
/**
* Break us out of any containing iframes
*
* @return void
*
* @since 1.5
*/
public static function noframes()
{
// Only load once
if (isset(static::$loaded[__METHOD__]))
{
return;
}
// Include MooTools framework
static::framework();
$js = "window.addEvent('domready', function () {if (top == self) {document.documentElement.style.display = 'block'; }" .
" else {top.location = self.location; }});";
$document = JFactory::getDocument();
$document->addStyleDeclaration('html { display:none }');
$document->addScriptDeclaration($js);
JResponse::setHeader('X-Frames-Options', 'SAMEORIGIN');
static::$loaded[__METHOD__] = true;
}
/**
* Internal method to get a JavaScript object notation string from an array
*
* @param array $array The array to convert to JavaScript object notation
*
* @return string JavaScript object notation representation of the array
*
* @since 1.5
* @deprecated 13.3 (Platform) & 4.0 (CMS) - Use JHtml::getJSObject() instead.
*/
protected static function _getJSObject($array = array())
{
JLog::add('JHtmlBehavior::_getJSObject() is deprecated. JHtml::getJSObject() instead..', JLog::WARNING, 'deprecated');
return JHtml::getJSObject($array);
}
/**
* Internal method to translate the JavaScript Calendar
*
* @return string JavaScript that translates the object
*
* @since 1.5
*/
protected static function calendartranslation()
{
static $jsscript = 0;
// Guard clause, avoids unnecessary nesting
if ($jsscript)
{
return false;
}
$jsscript = 1;
// To keep the code simple here, run strings through JText::_() using array_map()
$callback = array('JText','_');
$weekdays_full = array_map(
$callback, array(
'SUNDAY', 'MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY', 'SUNDAY'
)
);
$weekdays_short = array_map(
$callback,
array(
'SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT', 'SUN'
)
);
$months_long = array_map(
$callback, array(
'JANUARY', 'FEBRUARY', 'MARCH', 'APRIL', 'MAY', 'JUNE',
'JULY', 'AUGUST', 'SEPTEMBER', 'OCTOBER', 'NOVEMBER', 'DECEMBER'
)
);
$months_short = array_map(
$callback, array(
'JANUARY_SHORT', 'FEBRUARY_SHORT', 'MARCH_SHORT', 'APRIL_SHORT', 'MAY_SHORT', 'JUNE_SHORT',
'JULY_SHORT', 'AUGUST_SHORT', 'SEPTEMBER_SHORT', 'OCTOBER_SHORT', 'NOVEMBER_SHORT', 'DECEMBER_SHORT'
)
);
// This will become an object in Javascript but define it first in PHP for readability
$text = array(
'INFO' => JText::_('JLIB_HTML_BEHAVIOR_ABOUT_THE_CALENDAR'),
'ABOUT' => "DHTML Date/Time Selector\n"
. "(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n"
. "For latest version visit: http://www.dynarch.com/projects/calendar/\n"
. "Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details."
. "\n\n"
. JText::_('JLIB_HTML_BEHAVIOR_DATE_SELECTION')
. JText::_('JLIB_HTML_BEHAVIOR_YEAR_SELECT')
. JText::_('JLIB_HTML_BEHAVIOR_MONTH_SELECT')
. JText::_('JLIB_HTML_BEHAVIOR_HOLD_MOUSE'),
'ABOUT_TIME' => "\n\n"
. "Time selection:\n"
. "- Click on any of the time parts to increase it\n"
. "- or Shift-click to decrease it\n"
. "- or click and drag for faster selection.",
'PREV_YEAR' => JText::_('JLIB_HTML_BEHAVIOR_PREV_YEAR_HOLD_FOR_MENU'),
'PREV_MONTH' => JText::_('JLIB_HTML_BEHAVIOR_PREV_MONTH_HOLD_FOR_MENU'),
'GO_TODAY' => JText::_('JLIB_HTML_BEHAVIOR_GO_TODAY'),
'NEXT_MONTH' => JText::_('JLIB_HTML_BEHAVIOR_NEXT_MONTH_HOLD_FOR_MENU'),
'SEL_DATE' => JText::_('JLIB_HTML_BEHAVIOR_SELECT_DATE'),
'DRAG_TO_MOVE' => JText::_('JLIB_HTML_BEHAVIOR_DRAG_TO_MOVE'),
'PART_TODAY' => JText::_('JLIB_HTML_BEHAVIOR_TODAY'),
'DAY_FIRST' => JText::_('JLIB_HTML_BEHAVIOR_DISPLAY_S_FIRST'),
'WEEKEND' => "0,6",
'CLOSE' => JText::_('JLIB_HTML_BEHAVIOR_CLOSE'),
'TODAY' => JText::_('JLIB_HTML_BEHAVIOR_TODAY'),
'TIME_PART' => JText::_('JLIB_HTML_BEHAVIOR_SHIFT_CLICK_OR_DRAG_TO_CHANGE_VALUE'),
'DEF_DATE_FORMAT' => "%Y-%m-%d",
'TT_DATE_FORMAT' => JText::_('JLIB_HTML_BEHAVIOR_TT_DATE_FORMAT'),
'WK' => JText::_('JLIB_HTML_BEHAVIOR_WK'),
'TIME' => JText::_('JLIB_HTML_BEHAVIOR_TIME')
);
return 'Calendar._DN = ' . json_encode($weekdays_full) . ';'
. ' Calendar._SDN = ' . json_encode($weekdays_short) . ';'
. ' Calendar._FD = 0;'
. ' Calendar._MN = ' . json_encode($months_long) . ';'
. ' Calendar._SMN = ' . json_encode($months_short) . ';'
. ' Calendar._TT = ' . json_encode($text) . ';';
}
}

View File

@ -0,0 +1,852 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage HTML
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
/**
* Utility class for Bootstrap elements.
*
* @package Joomla.Libraries
* @subpackage HTML
* @since 3.0
*/
abstract class JHtmlBootstrap
{
/**
* @var array Array containing information for loaded files
* @since 3.0
*/
protected static $loaded = array();
/**
* Add javascript support for the Bootstrap affix plugin
*
* @param string $selector Unique selector for the element to be affixed.
* @param array $params An array of options.
* Options for the affix plugin can be:
* - offset number|function|object Pixels to offset from screen when calculating position of scroll.
* If a single number is provided, the offset will be applied in both top
* and left directions. To listen for a single direction, or multiple
* unique offsets, just provide an object offset: { x: 10 }.
* Use a function when you need to dynamically provide an offset
* (useful for some responsive designs).
*
* @return void
*
* @since 3.1
*/
public static function affix($selector = 'affix', $params = array())
{
$sig = md5(serialize(array($selector, $params)));
if (!isset(static::$loaded[__METHOD__][$sig]))
{
// Include Bootstrap framework
static::framework();
// Setup options object
$opt['offset'] = isset($params['offset']) ? $params['offset'] : 10;
$options = JHtml::getJSObject($opt);
// Attach the carousel to document
JFactory::getDocument()->addScriptDeclaration(
"(function($){
$('#$selector').affix($options);
})(jQuery);"
);
// Set static array
static::$loaded[__METHOD__][$sig] = true;
}
return;
}
/**
* Add javascript support for Bootstrap alerts
*
* @param string $selector Common class for the alerts
*
* @return void
*
* @since 3.0
*/
public static function alert($selector = 'alert')
{
// Only load once
if (isset(static::$loaded[__METHOD__][$selector]))
{
return;
}
// Include Bootstrap framework
static::framework();
// Attach the alerts to the document
JFactory::getDocument()->addScriptDeclaration(
"(function($){
$('.$selector').alert();
})(jQuery);"
);
static::$loaded[__METHOD__][$selector] = true;
return;
}
/**
* Add javascript support for Bootstrap buttons
*
* @param string $selector Common class for the buttons
*
* @return void
*
* @since 3.1
*/
public static function button($selector = 'button')
{
// Only load once
if (isset(static::$loaded[__METHOD__][$selector]))
{
return;
}
// Include Bootstrap framework
static::framework();
// Attach the alerts to the document
JFactory::getDocument()->addScriptDeclaration(
"(function($){
$('.$selector').button();
})(jQuery);"
);
static::$loaded[__METHOD__][$selector] = true;
return;
}
/**
* Add javascript support for Bootstrap carousels
*
* @param string $selector Common class for the carousels.
* @param array $params An array of options for the modal.
* Options for the modal can be:
* - interval number The amount of time to delay between automatically cycling an item.
* If false, carousel will not automatically cycle.
* - pause string Pauses the cycling of the carousel on mouseenter and resumes the cycling
* of the carousel on mouseleave.
*
* @return void
*
* @since 3.0
*/
public static function carousel($selector = 'carousel', $params = array())
{
$sig = md5(serialize(array($selector, $params)));
if (!isset(static::$loaded[__METHOD__][$sig]))
{
// Include Bootstrap framework
static::framework();
// Setup options object
$opt['interval'] = isset($params['interval']) ? (int) $params['interval'] : 5000;
$opt['pause'] = isset($params['pause']) ? $params['pause'] : 'hover';
$options = JHtml::getJSObject($opt);
// Attach the carousel to document
JFactory::getDocument()->addScriptDeclaration(
"(function($){
$('.$selector').carousel($options);
})(jQuery);"
);
// Set static array
static::$loaded[__METHOD__][$sig] = true;
}
return;
}
/**
* Add javascript support for Bootstrap dropdowns
*
* @param string $selector Common class for the dropdowns
*
* @return void
*
* @since 3.0
*/
public static function dropdown($selector = 'dropdown-toggle')
{
// Only load once
if (isset(static::$loaded[__METHOD__][$selector]))
{
return;
}
// Include Bootstrap framework
static::framework();
// Attach the dropdown to the document
JFactory::getDocument()->addScriptDeclaration(
"(function($){
$('.$selector').dropdown();
})(jQuery);"
);
static::$loaded[__METHOD__][$selector] = true;
return;
}
/**
* Method to load the Bootstrap JavaScript framework into the document head
*
* If debugging mode is on an uncompressed version of Bootstrap is included for easier debugging.
*
* @param mixed $debug Is debugging mode on? [optional]
*
* @return void
*
* @since 3.0
*/
public static function framework($debug = null)
{
// Only load once
if (!empty(static::$loaded[__METHOD__]))
{
return;
}
// Load jQuery
JHtml::_('jquery.framework');
// If no debugging value is set, use the configuration setting
if ($debug === null)
{
$config = JFactory::getConfig();
$debug = (boolean) $config->get('debug');
}
JHtml::_('script', 'jui/bootstrap.min.js', false, true, false, false, $debug);
static::$loaded[__METHOD__] = true;
return;
}
/**
* Add javascript support for Bootstrap modals
*
* @param string $selector The ID selector for the modal.
* @param array $params An array of options for the modal.
* Options for the modal can be:
* - backdrop boolean Includes a modal-backdrop element.
* - keyboard boolean Closes the modal when escape key is pressed.
* - show boolean Shows the modal when initialized.
* - remote string An optional remote URL to load
*
* @return void
*
* @since 3.0
*/
public static function modal($selector = 'modal', $params = array())
{
$sig = md5(serialize(array($selector, $params)));
if (!isset(static::$loaded[__METHOD__][$sig]))
{
// Include Bootstrap framework
static::framework();
// Setup options object
$opt['backdrop'] = isset($params['backdrop']) ? (boolean) $params['backdrop'] : true;
$opt['keyboard'] = isset($params['keyboard']) ? (boolean) $params['keyboard'] : true;
$opt['show'] = isset($params['show']) ? (boolean) $params['show'] : true;
$opt['remote'] = isset($params['remote']) ? $params['remote'] : '';
$options = JHtml::getJSObject($opt);
// Attach the modal to document
JFactory::getDocument()->addScriptDeclaration(
"(function($){
$('#$selector').modal($options);
})(jQuery);"
);
// Set static array
static::$loaded[__METHOD__][$sig] = true;
}
return;
}
/**
* Method to render a Bootstrap modal
*
* @param string $selector The ID selector for the modal.
* @param array $params An array of options for the modal.
* @param string $footer Optional markup for the modal footer
*
* @return string HTML markup for a modal
*
* @since 3.0
*/
public static function renderModal($selector = 'modal', $params = array(), $footer = '')
{
// Ensure the behavior is loaded
static::modal($selector, $params);
$html = "<div class=\"modal hide fade\" id=\"" . $selector . "\">\n";
$html .= "<div class=\"modal-header\">\n";
$html .= "<button type=\"button\" class=\"close\" data-dismiss=\"modal\">×</button>\n";
$html .= "<h3>" . $params['title'] . "</h3>\n";
$html .= "</div>\n";
$html .= "<div id=\"" . $selector . "-container\">\n";
$html .= "</div>\n";
$html .= "</div>\n";
$html .= "<script>";
$html .= "jQuery('#" . $selector . "').on('show', function () {\n";
$html .= "document.getElementById('" . $selector . "-container').innerHTML = '<div class=\"modal-body\"><iframe class=\"iframe\" src=\""
. $params['url'] . "\" height=\"" . $params['height'] . "\" width=\"" . $params['width'] . "\"></iframe></div>" . $footer . "';\n";
$html .= "});\n";
$html .= "</script>";
return $html;
}
/**
* Add javascript support for Bootstrap popovers
*
* Use element's Title as popover content
*
* @param string $selector Selector for the tooltip
* @param array $params An array of options for the tooltip.
* Options for the tooltip can be:
* animation boolean apply a css fade transition to the tooltip
* html boolean Insert HTML into the tooltip. If false, jQuery's text method will be used to insert
* content into the dom.
* placement string|function how to position the tooltip - top | bottom | left | right
* selector string If a selector is provided, tooltip objects will be delegated to the specified targets.
* trigger string how tooltip is triggered - hover | focus | manual
* title string|function default title value if `title` tag isn't present
* content string|function default content value if `data-content` attribute isn't present
* delay number|object delay showing and hiding the tooltip (ms) - does not apply to manual trigger type
* If a number is supplied, delay is applied to both hide/show
* Object structure is: delay: { show: 500, hide: 100 }
* container string|boolean Appends the popover to a specific element: { container: 'body' }
*
* @return void
*
* @since 3.0
*/
public static function popover($selector = '.hasPopover', $params = array())
{
// Only load once
if (isset(static::$loaded[__METHOD__][$selector]))
{
return;
}
// Include Bootstrap framework
static::framework();
$opt['animation'] = isset($params['animation']) ? $params['animation'] : null;
$opt['html'] = isset($params['html']) ? $params['html'] : true;
$opt['placement'] = isset($params['placement']) ? $params['placement'] : null;
$opt['selector'] = isset($params['selector']) ? $params['selector'] : null;
$opt['title'] = isset($params['title']) ? $params['title'] : null;
$opt['trigger'] = isset($params['trigger']) ? $params['trigger'] : 'hover';
$opt['content'] = isset($params['content']) ? $params['content'] : null;
$opt['delay'] = isset($params['delay']) ? $params['delay'] : null;
$opt['container'] = isset($params['container']) ? $params['container'] : false;
$options = JHtml::getJSObject($opt);
// Attach the popover to the document
JFactory::getDocument()->addScriptDeclaration(
"jQuery(document).ready(function()
{
jQuery('" . $selector . "').popover(" . $options . ");
});"
);
static::$loaded[__METHOD__][$selector] = true;
return;
}
/**
* Add javascript support for Bootstrap ScrollSpy
*
* @param string $selector The ID selector for the ScrollSpy element.
* @param array $params An array of options for the ScrollSpy.
* Options for the modal can be:
* - offset number Pixels to offset from top when calculating position of scroll.
*
* @return void
*
* @since 3.0
*/
public static function scrollspy($selector = 'navbar', $params = array())
{
$sig = md5(serialize(array($selector, $params)));
if (!isset(static::$loaded[__METHOD__][$sig]))
{
// Include Bootstrap framework
static::framework();
// Setup options object
$opt['offset'] = isset($params['offset']) ? (int) $params['offset'] : 10;
$options = JHtml::getJSObject($opt);
// Attach ScrollSpy to document
JFactory::getDocument()->addScriptDeclaration(
"(function($){
$('#$selector').scrollspy($options);
})(jQuery);"
);
// Set static array
static::$loaded[__METHOD__][$sig] = true;
}
return;
}
/**
* Add javascript support for Bootstrap tooltips
*
* Add a title attribute to any element in the form
* title="title::text"
*
* @param string $selector The ID selector for the tooltip.
* @param array $params An array of options for the tooltip.
* Options for the tooltip can be:
* - animation boolean Apply a CSS fade transition to the tooltip
* - html boolean Insert HTML into the tooltip. If false, jQuery's text method will be used to insert
* content into the dom.
* - placement string|function How to position the tooltip - top | bottom | left | right
* - selector string If a selector is provided, tooltip objects will be delegated to the specified targets.
* - title string|function Default title value if `title` tag isn't present
* - trigger string How tooltip is triggered - hover | focus | manual
* - delay integer Delay showing and hiding the tooltip (ms) - does not apply to manual trigger type
* If a number is supplied, delay is applied to both hide/show
* Object structure is: delay: { show: 500, hide: 100 }
* - container string|boolean Appends the popover to a specific element: { container: 'body' }
*
* @return void
*
* @since 3.0
*/
public static function tooltip($selector = '.hasTooltip', $params = array())
{
if (!isset(static::$loaded[__METHOD__][$selector]))
{
// Include Bootstrap framework
static::framework();
// Setup options object
$opt['animation'] = isset($params['animation']) ? (boolean) $params['animation'] : null;
$opt['html'] = isset($params['html']) ? (boolean) $params['html'] : null;
$opt['placement'] = isset($params['placement']) ? (string) $params['placement'] : null;
$opt['selector'] = isset($params['selector']) ? (string) $params['selector'] : null;
$opt['title'] = isset($params['title']) ? (string) $params['title'] : null;
$opt['trigger'] = isset($params['trigger']) ? (string) $params['trigger'] : null;
$opt['delay'] = isset($params['delay']) ? (int) $params['delay'] : null;
$opt['container'] = isset($params['container']) ? (int) $params['container'] : false;
$opt['template'] = isset($params['template']) ? (string) $params['template'] : null;
$options = JHtml::getJSObject($opt);
// Attach tooltips to document
JFactory::getDocument()->addScriptDeclaration(
"jQuery(document).ready(function()
{
jQuery('" . $selector . "').tooltip(" . $options . ");
});"
);
// Set static array
static::$loaded[__METHOD__][$selector] = true;
}
return;
}
/**
* Add javascript support for Bootstrap typeahead
*
* @param string $selector The selector for the typeahead element.
* @param array $params An array of options for the typeahead element.
* Options for the tooltip can be:
* - source array, function The data source to query against. May be an array of strings or a function.
* The function is passed two arguments, the query value in the input field and the
* process callback. The function may be used synchronously by returning the data
* source directly or asynchronously via the process callback's single argument.
* - items number The max number of items to display in the dropdown.
* - minLength number The minimum character length needed before triggering autocomplete suggestions
* - matcher function The method used to determine if a query matches an item. Accepts a single argument,
* the item against which to test the query. Access the current query with this.query.
* Return a boolean true if query is a match.
* - sorter function Method used to sort autocomplete results. Accepts a single argument items and has
* the scope of the typeahead instance. Reference the current query with this.query.
* - updater function The method used to return selected item. Accepts a single argument, the item and
* has the scope of the typeahead instance.
* - highlighter function Method used to highlight autocomplete results. Accepts a single argument item and
* has the scope of the typeahead instance. Should return html.
*
* @return void
*
* @since 3.0
*/
public static function typeahead($selector = '.typeahead', $params = array())
{
if (!isset(static::$loaded[__METHOD__][$selector]))
{
// Include Bootstrap framework
static::framework();
// Setup options object
$opt['source'] = isset($params['source']) ? $params['source'] : '[]';
$opt['items'] = isset($params['items']) ? (int) $params['items'] : 8;
$opt['minLength'] = isset($params['minLength']) ? (int) $params['minLength'] : 1;
$opt['matcher'] = isset($params['matcher']) ? (string) $params['matcher'] : null;
$opt['sorter'] = isset($params['sorter']) ? (string) $params['sorter'] : null;
$opt['updater'] = isset($params['updater']) ? (string) $params['updater'] : null;
$opt['highlighter'] = isset($params['highlighter']) ? (int) $params['highlighter'] : null;
$options = JHtml::getJSObject($opt);
// Attach tooltips to document
JFactory::getDocument()->addScriptDeclaration(
"jQuery(document).ready(function()
{
jQuery('" . $selector . "').typeahead(" . $options . ");
});"
);
// Set static array
static::$loaded[__METHOD__][$selector] = true;
}
return;
}
/**
* Add javascript support for Bootstrap accordians and insert the accordian
*
* @param string $selector The ID selector for the tooltip.
* @param array $params An array of options for the tooltip.
* Options for the tooltip can be:
* - parent selector If selector then all collapsible elements under the specified parent will be closed when this
* collapsible item is shown. (similar to traditional accordion behavior)
* - toggle boolean Toggles the collapsible element on invocation
* - active string Sets the active slide during load
*
* @return string HTML for the accordian
*
* @since 3.0
*/
public static function startAccordion($selector = 'myAccordian', $params = array())
{
$sig = md5(serialize(array($selector, $params)));
if (!isset(static::$loaded[__METHOD__][$sig]))
{
// Include Bootstrap framework
static::framework();
// Setup options object
$opt['parent'] = isset($params['parent']) ? (boolean) $params['parent'] : false;
$opt['toggle'] = isset($params['toggle']) ? (boolean) $params['toggle'] : true;
$opt['active'] = isset($params['active']) ? (string) $params['active'] : '';
$options = JHtml::getJSObject($opt);
// Attach accordion to document
JFactory::getDocument()->addScriptDeclaration(
"(function($){
$('#$selector').collapse($options);
})(jQuery);"
);
// Set static array
static::$loaded[__METHOD__][$sig] = true;
static::$loaded[__METHOD__]['active'] = $opt['active'];
}
return '<div id="' . $selector . '" class="accordion">';
}
/**
* Close the current accordion
*
* @return string HTML to close the accordian
*
* @since 3.0
*/
public static function endAccordion()
{
return '</div>';
}
/**
* Begins the display of a new accordion slide.
*
* @param string $selector Identifier of the accordion group.
* @param string $text Text to display.
* @param string $id Identifier of the slide.
* @param string $class Class of the accordion group.
*
* @return string HTML to add the slide
*
* @since 3.0
*/
public static function addSlide($selector, $text, $id, $class = '')
{
$in = (static::$loaded['JHtmlBootstrap::startAccordion']['active'] == $id) ? ' in' : '';
$class = (!empty($class)) ? ' ' . $class : '';
$html = '<div class="accordion-group' . $class . '">'
. '<div class="accordion-heading">'
. '<strong><a href="#' . $id . '" data-parent="#' . $selector . '" data-toggle="collapse" class="accordion-toggle">'
. $text
. '</a></strong>'
. '</div>'
. '<div class="accordion-body collapse' . $in . '" id="' . $id . '">'
. '<div class="accordion-inner">';
return $html;
}
/**
* Close the current slide
*
* @return string HTML to close the slide
*
* @since 3.0
*/
public static function endSlide()
{
return '</div></div></div>';
}
/**
* Creates a tab pane
*
* @param string $selector The pane identifier.
* @param array $params The parameters for the pane
*
* @return string
*
* @since 3.1
*/
public static function startTabSet($selector = 'myTab', $params = array())
{
$sig = md5(serialize(array($selector, $params)));
if (!isset(static::$loaded[__METHOD__][$sig]))
{
// Include Bootstrap framework
static::framework();
// Setup options object
$opt['active'] = (isset($params['active']) && ($params['active'])) ? (string) $params['active'] : '';
// Attach tabs to document
JFactory::getDocument()
->addScriptDeclaration(JLayoutHelper::render('libraries.cms.html.bootstrap.starttabsetscript', array('selector' => $selector)));
// Set static array
static::$loaded[__METHOD__][$sig] = true;
static::$loaded[__METHOD__][$selector]['active'] = $opt['active'];
}
$html = JLayoutHelper::render('libraries.cms.html.bootstrap.starttabset', array('selector' => $selector));
return $html;
}
/**
* Close the current tab pane
*
* @return string HTML to close the pane
*
* @since 3.1
*/
public static function endTabSet()
{
$html = JLayoutHelper::render('libraries.cms.html.bootstrap.endtabset');
return $html;
}
/**
* Begins the display of a new tab content panel.
*
* @param string $selector Identifier of the panel.
* @param string $id The ID of the div element
* @param string $title The title text for the new UL tab
*
* @return string HTML to start a new panel
*
* @since 3.1
*/
public static function addTab($selector, $id, $title)
{
static $tabScriptLayout = null;
static $tabLayout = null;
$tabScriptLayout = is_null($tabScriptLayout) ? new JLayoutFile('libraries.cms.html.bootstrap.addtabscript') : $tabScriptLayout;
$tabLayout = is_null($tabLayout) ? new JLayoutFile('libraries.cms.html.bootstrap.addtab') : $tabLayout;
$active = (static::$loaded['JHtmlBootstrap::startTabSet'][$selector]['active'] == $id) ? ' active' : '';
// Inject tab into UL
JFactory::getDocument()
->addScriptDeclaration($tabScriptLayout->render(array('selector' => $selector,'id' => $id, 'active' => $active, 'title' => $title)));
$html = $tabLayout->render(array('id' => $id, 'active' => $active));
return $html;
}
/**
* Close the current tab content panel
*
* @return string HTML to close the pane
*
* @since 3.1
*/
public static function endTab()
{
$html = JLayoutHelper::render('libraries.cms.html.bootstrap.endtab');
return $html;
}
/**
* Creates a tab pane
*
* @param string $selector The pane identifier.
* @param array $params The parameters for the pane
*
* @return string
*
* @since 3.0
* @deprecated 4.0 Use JHtml::_('bootstrap.startTabSet') instead.
*/
public static function startPane($selector = 'myTab', $params = array())
{
$sig = md5(serialize(array($selector, $params)));
if (!isset(static::$loaded['JHtmlBootstrap::startTabSet'][$sig]))
{
// Include Bootstrap framework
static::framework();
// Setup options object
$opt['active'] = isset($params['active']) ? (string) $params['active'] : '';
// Attach tooltips to document
JFactory::getDocument()->addScriptDeclaration(
"(function($){
$('#$selector a').click(function (e) {
e.preventDefault();
$(this).tab('show');
});
})(jQuery);"
);
// Set static array
static::$loaded['JHtmlBootstrap::startTabSet'][$sig] = true;
static::$loaded['JHtmlBootstrap::startTabSet'][$selector]['active'] = $opt['active'];
}
return '<div class="tab-content" id="' . $selector . 'Content">';
}
/**
* Close the current tab pane
*
* @return string HTML to close the pane
*
* @since 3.0
* @deprecated 4.0 Use JHtml::_('bootstrap.endTabSet') instead.
*/
public static function endPane()
{
return '</div>';
}
/**
* Begins the display of a new tab content panel.
*
* @param string $selector Identifier of the panel.
* @param string $id The ID of the div element
*
* @return string HTML to start a new panel
*
* @since 3.0
* @deprecated 4.0 Use JHtml::_('bootstrap.addTab') instead.
*/
public static function addPanel($selector, $id)
{
$active = (static::$loaded['JHtmlBootstrap::startTabSet'][$selector]['active'] == $id) ? ' active' : '';
return '<div id="' . $id . '" class="tab-pane' . $active . '">';
}
/**
* Close the current tab content panel
*
* @return string HTML to close the pane
*
* @since 3.0
* @deprecated 4.0 Use JHtml::_('bootstrap.endTab') instead.
*/
public static function endPanel()
{
return '</div>';
}
/**
* Loads CSS files needed by Bootstrap
*
* @param boolean $includeMainCss If true, main bootstrap.css files are loaded
* @param string $direction rtl or ltr direction. If empty, ltr is assumed
* @param array $attribs Optional array of attributes to be passed to JHtml::_('stylesheet')
*
* @return void
*
* @since 3.0
*/
public static function loadCss($includeMainCss = true, $direction = 'ltr', $attribs = array())
{
// Load Bootstrap main CSS
if ($includeMainCss)
{
JHtml::_('stylesheet', 'jui/bootstrap.min.css', $attribs, true);
JHtml::_('stylesheet', 'jui/bootstrap-responsive.min.css', $attribs, true);
JHtml::_('stylesheet', 'jui/bootstrap-extended.css', $attribs, true);
}
// Load Bootstrap RTL CSS
if ($direction === 'rtl')
{
JHtml::_('stylesheet', 'jui/bootstrap-rtl.css', $attribs, true);
}
}
}

View File

@ -0,0 +1,166 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage HTML
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_BASE') or die;
/**
* Utility class for categories
*
* @package Joomla.Libraries
* @subpackage HTML
* @since 1.5
*/
abstract class JHtmlCategory
{
/**
* Cached array of the category items.
*
* @var array
* @since 1.5
*/
protected static $items = array();
/**
* Returns an array of categories for the given extension.
*
* @param string $extension The extension option e.g. com_something.
* @param array $config An array of configuration options. By default, only
* published and unpublished categories are returned.
*
* @return array
*
* @since 1.5
*/
public static function options($extension, $config = array('filter.published' => array(0, 1)))
{
$hash = md5($extension . '.' . serialize($config));
if (!isset(static::$items[$hash]))
{
$config = (array) $config;
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select('a.id, a.title, a.level')
->from('#__categories AS a')
->where('a.parent_id > 0');
// Filter on extension.
$query->where('extension = ' . $db->quote($extension));
// Filter on the published state
if (isset($config['filter.published']))
{
if (is_numeric($config['filter.published']))
{
$query->where('a.published = ' . (int) $config['filter.published']);
}
elseif (is_array($config['filter.published']))
{
JArrayHelper::toInteger($config['filter.published']);
$query->where('a.published IN (' . implode(',', $config['filter.published']) . ')');
}
}
// Filter on the language
if (isset($config['filter.language']))
{
if (is_string($config['filter.language']))
{
$query->where('a.language = ' . $db->quote($config['filter.language']));
}
elseif (is_array($config['filter.language']))
{
foreach ($config['filter.language'] as &$language)
{
$language = $db->quote($language);
}
$query->where('a.language IN (' . implode(',', $config['filter.language']) . ')');
}
}
$query->order('a.lft');
$db->setQuery($query);
$items = $db->loadObjectList();
// Assemble the list options.
static::$items[$hash] = array();
foreach ($items as &$item)
{
$repeat = ($item->level - 1 >= 0) ? $item->level - 1 : 0;
$item->title = str_repeat('- ', $repeat) . $item->title;
static::$items[$hash][] = JHtml::_('select.option', $item->id, $item->title);
}
}
return static::$items[$hash];
}
/**
* Returns an array of categories for the given extension.
*
* @param string $extension The extension option.
* @param array $config An array of configuration options. By default, only published and unpublished categories are returned.
*
* @return array Categories for the extension
*
* @since 1.6
*/
public static function categories($extension, $config = array('filter.published' => array(0, 1)))
{
$hash = md5($extension . '.' . serialize($config));
if (!isset(static::$items[$hash]))
{
$config = (array) $config;
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select('a.id, a.title, a.level, a.parent_id')
->from('#__categories AS a')
->where('a.parent_id > 0');
// Filter on extension.
$query->where('extension = ' . $db->quote($extension));
// Filter on the published state
if (isset($config['filter.published']))
{
if (is_numeric($config['filter.published']))
{
$query->where('a.published = ' . (int) $config['filter.published']);
}
elseif (is_array($config['filter.published']))
{
JArrayHelper::toInteger($config['filter.published']);
$query->where('a.published IN (' . implode(',', $config['filter.published']) . ')');
}
}
$query->order('a.lft');
$db->setQuery($query);
$items = $db->loadObjectList();
// Assemble the list options.
static::$items[$hash] = array();
foreach ($items as &$item)
{
$repeat = ($item->level - 1 >= 0) ? $item->level - 1 : 0;
$item->title = str_repeat('- ', $repeat) . $item->title;
static::$items[$hash][] = JHtml::_('select.option', $item->id, $item->title);
}
// Special "Add to root" option:
static::$items[$hash][] = JHtml::_('select.option', '1', JText::_('JLIB_HTML_ADD_TO_ROOT'));
}
return static::$items[$hash];
}
}

View File

@ -0,0 +1,47 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage HTML
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
/**
* Utility class to fire onContentPrepare for non-article based content.
*
* @package Joomla.Libraries
* @subpackage HTML
* @since 1.5
*/
abstract class JHtmlContent
{
/**
* Fire onContentPrepare for content that isn't part of an article.
*
* @param string $text The content to be transformed.
* @param array $params The content params.
* @param string $context The context of the content to be transformed.
*
* @return string The content after transformation.
*
* @since 1.5
*/
public static function prepare($text, $params = null, $context = 'text')
{
if ($params === null)
{
$params = new JObject;
}
$article = new stdClass;
$article->text = $text;
JPluginHelper::importPlugin('content');
$dispatcher = JEventDispatcher::getInstance();
$dispatcher->trigger('onContentPrepare', array($context, &$article, &$params, 0));
return $article->text;
}
}

View File

@ -0,0 +1,66 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage HTML
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
/**
* Utility class working with content language select lists
*
* @package Joomla.Libraries
* @subpackage HTML
* @since 1.6
*/
abstract class JHtmlContentLanguage
{
/**
* Cached array of the content language items.
*
* @var array
* @since 1.6
*/
protected static $items = null;
/**
* Get a list of the available content language items.
*
* @param boolean $all True to include All (*)
* @param boolean $translate True to translate All
*
* @return string
*
* @see JFormFieldContentLanguage
* @since 1.6
*/
public static function existing($all = false, $translate = false)
{
if (empty(static::$items))
{
// Get the database object and a new query object.
$db = JFactory::getDbo();
$query = $db->getQuery(true);
// Build the query.
$query->select('a.lang_code AS value, a.title AS text, a.title_native')
->from('#__languages AS a')
->where('a.published >= 0')
->order('a.title');
// Set the query and load the options.
$db->setQuery($query);
static::$items = $db->loadObjectList();
if ($all)
{
array_unshift(static::$items, new JObject(array('value' => '*', 'text' => $translate ? JText::alt('JALL', 'language') : 'JALL_LANGUAGE')));
}
}
return static::$items;
}
}

View File

@ -0,0 +1,89 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage HTML
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
/**
* Extended Utility class for handling date display.
*
* @package Joomla.Libraries
* @subpackage HTML
* @since 2.5
*/
abstract class JHtmlDate
{
/**
* Function to convert a static time into a relative measurement
*
* @param string $date The date to convert
* @param string $unit The optional unit of measurement to return
* if the value of the diff is greater than one
* @param string $time An optional time to compare to, defaults to now
*
* @return string The converted time string
*
* @since 2.5
*/
public static function relative($date, $unit = null, $time = null)
{
if (is_null($time))
{
// Get now
$time = JFactory::getDate('now');
}
// Get the difference in seconds between now and the time
$diff = strtotime($time) - strtotime($date);
// Less than a minute
if ($diff < 60)
{
return JText::_('JLIB_HTML_DATE_RELATIVE_LESSTHANAMINUTE');
}
// Round to minutes
$diff = round($diff / 60);
// 1 to 59 minutes
if ($diff < 60 || $unit == 'minute')
{
return JText::plural('JLIB_HTML_DATE_RELATIVE_MINUTES', $diff);
}
// Round to hours
$diff = round($diff / 60);
// 1 to 23 hours
if ($diff < 24 || $unit == 'hour')
{
return JText::plural('JLIB_HTML_DATE_RELATIVE_HOURS', $diff);
}
// Round to days
$diff = round($diff / 24);
// 1 to 6 days
if ($diff < 7 || $unit == 'day')
{
return JText::plural('JLIB_HTML_DATE_RELATIVE_DAYS', $diff);
}
// Round to weeks
$diff = round($diff / 7);
// 1 to 4 weeks
if ($diff <= 4 || $unit == 'week')
{
return JText::plural('JLIB_HTML_DATE_RELATIVE_WEEKS', $diff);
}
// Over a month, return the absolute time
return JHtml::_('date', $date);
}
}

View File

@ -0,0 +1,355 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage HTML
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
/**
* HTML utility class for building a dropdown menu
*
* @package Joomla.Libraries
* @subpackage HTML
* @since 3.0
*/
abstract class JHtmlDropdown
{
/**
* @var array Array containing information for loaded files
* @since 3.0
*/
protected static $loaded = array();
/**
* @var string HTML markup for the dropdown list
* @since 3.0
*/
protected static $dropDownList = null;
/**
* Method to inject needed script
*
* @return void
*
* @since 3.0
*/
public static function init()
{
// Only load once
if (isset(static::$loaded[__METHOD__]))
{
return;
}
// Depends on Bootstrap
JHtml::_('bootstrap.framework');
JFactory::getDocument()->addScriptDeclaration("
(function($){
$(document).ready(function (){
$('.has-context')
.mouseenter(function (){
$('.btn-group',$(this)).show();
})
.mouseleave(function (){
$('.btn-group',$(this)).hide();
$('.btn-group',$(this)).removeClass('open');
});
contextAction =function (cbId, task)
{
$('input[name=\"cid[]\"]').removeAttr('checked');
$('#' + cbId).attr('checked','checked');
Joomla.submitbutton(task);
}
});
})(jQuery);
"
);
// Set static array
static::$loaded[__METHOD__] = true;
return;
}
/**
* Method to start a new dropdown menu
*
* @return void
*
* @since 3.0
*/
public static function start()
{
// Only start once
if (isset(static::$loaded[__METHOD__]) && static::$loaded[__METHOD__] == true)
{
return;
}
$dropDownList = '<div class="btn-group" style="margin-left:6px;display:none">
<a href="#" data-toggle="dropdown" class="dropdown-toggle btn btn-mini">
<span class="caret"></span>
</a>
<ul class="dropdown-menu">';
static::$dropDownList = $dropDownList;
static::$loaded[__METHOD__] = true;
return;
}
/**
* Method to render current dropdown menu
*
* @return string HTML markup for the dropdown list
*
* @since 3.0
*/
public static function render()
{
$dropDownList = static::$dropDownList;
$dropDownList .= '</ul></div>';
static::$dropDownList = null;
static::$loaded['JHtmlDropdown::start'] = false;
return $dropDownList;
}
/**
* Append an edit item to the current dropdown menu
*
* @param integer $id Record ID
* @param string $prefix Task prefix
* @param string $customLink The custom link if dont use default Joomla action format
*
* @return void
*
* @since 3.0
*/
public static function edit($id, $prefix = '', $customLink = '')
{
static::start();
if (!$customLink)
{
$option = JFactory::getApplication()->input->getCmd('option');
$link = 'index.php?option=' . $option;
}
else
{
$link = $customLink;
}
$link .= '&task=' . $prefix . 'edit&id=' . $id;
$link = JRoute::_($link);
static::addCustomItem(JText::_('JACTION_EDIT'), $link);
return;
}
/**
* Append a publish item to the current dropdown menu
*
* @param string $checkboxId ID of corresponding checkbox of the record
* @param string $prefix The task prefix
*
* @return void
*
* @since 3.0
*/
public static function publish($checkboxId, $prefix = '')
{
$task = $prefix . 'publish';
static::addCustomItem(JText::_('JTOOLBAR_PUBLISH'), 'javascript:void(0)', 'onclick="contextAction(\'' . $checkboxId . '\', \'' . $task . '\')"');
return;
}
/**
* Append an unpublish item to the current dropdown menu
*
* @param string $checkboxId ID of corresponding checkbox of the record
* @param string $prefix The task prefix
*
* @return void
*
* @since 3.0
*/
public static function unpublish($checkboxId, $prefix = '')
{
$task = $prefix . 'unpublish';
static::addCustomItem(JText::_('JTOOLBAR_UNPUBLISH'), 'javascript:void(0)', 'onclick="contextAction(\'' . $checkboxId . '\', \'' . $task . '\')"');
return;
}
/**
* Append a featured item to the current dropdown menu
*
* @param string $checkboxId ID of corresponding checkbox of the record
* @param string $prefix The task prefix
*
* @return void
*
* @since 3.0
*/
public static function featured($checkboxId, $prefix = '')
{
$task = $prefix . 'featured';
static::addCustomItem(JText::_('JFEATURED'), 'javascript:void(0)', 'onclick="contextAction(\'' . $checkboxId . '\', \'' . $task . '\')"');
return;
}
/**
* Append an unfeatured item to the current dropdown menu
*
* @param string $checkboxId ID of corresponding checkbox of the record
* @param string $prefix The task prefix
*
* @return void
*
* @since 3.0
*/
public static function unfeatured($checkboxId, $prefix = '')
{
$task = $prefix . 'unfeatured';
static::addCustomItem(JText::_('JUNFEATURED'), 'javascript:void(0)', 'onclick="contextAction(\'' . $checkboxId . '\', \'' . $task . '\')"');
return;
}
/**
* Append an archive item to the current dropdown menu
*
* @param string $checkboxId ID of corresponding checkbox of the record
* @param string $prefix The task prefix
*
* @return void
*
* @since 3.0
*/
public static function archive($checkboxId, $prefix = '')
{
$task = $prefix . 'archive';
static::addCustomItem(JText::_('JTOOLBAR_ARCHIVE'), 'javascript:void(0)', 'onclick="contextAction(\'' . $checkboxId . '\', \'' . $task . '\')"');
return;
}
/**
* Append an unarchive item to the current dropdown menu
*
* @param string $checkboxId ID of corresponding checkbox of the record
* @param string $prefix The task prefix
*
* @return void
*
* @since 3.0
*/
public static function unarchive($checkboxId, $prefix = '')
{
$task = $prefix . 'unpublish';
static::addCustomItem(JText::_('JTOOLBAR_UNARCHIVE'), 'javascript:void(0)', 'onclick="contextAction(\'' . $checkboxId . '\', \'' . $task . '\')"');
return;
}
/**
* Append a trash item to the current dropdown menu
*
* @param string $checkboxId ID of corresponding checkbox of the record
* @param string $prefix The task prefix
*
* @return void
*
* @since 3.0
*/
public static function trash($checkboxId, $prefix = '')
{
$task = $prefix . 'trash';
static::addCustomItem(JText::_('JTOOLBAR_TRASH'), 'javascript:void(0)', 'onclick="contextAction(\'' . $checkboxId . '\', \'' . $task . '\')"');
return;
}
/**
* Append an untrash item to the current dropdown menu
*
* @param string $checkboxId ID of corresponding checkbox of the record
* @param string $prefix The task prefix
*
* @return void
*
* @since 3.0
*/
public static function untrash($checkboxId, $prefix = '')
{
$task = $prefix . 'publish';
static::addCustomItem(JText::_('JTOOLBAR_UNTRASH'), 'javascript:void(0)', 'onclick="contextAction(\'' . $checkboxId . '\', \'' . $task . '\')"');
return;
}
/**
* Append a checkin item to the current dropdown menu
*
* @param string $checkboxId ID of corresponding checkbox of the record
* @param string $prefix The task prefix
*
* @return void
*
* @since 3.0
*/
public static function checkin($checkboxId, $prefix = '')
{
$task = $prefix . 'checkin';
static::addCustomItem(JText::_('JTOOLBAR_CHECKIN'), 'javascript:void(0)', 'onclick="contextAction(\'' . $checkboxId . '\', \'' . $task . '\')"');
return;
}
/**
* Writes a divider between dropdown items
*
* @return void
*
* @since 3.0
*/
public static function divider()
{
static::$dropDownList .= '<li class="divider"></li>';
return;
}
/**
* Append a custom item to current dropdown menu
*
* @param string $label The label of item
* @param string $link The link of item
* @param string $linkAttributes Custom link attributes
* @param string $className Class name of item
* @param boolean $ajaxLoad True if using ajax load when item clicked
* @param string $jsCallBackFunc Javascript function name, called when ajax load successfully
*
* @return void
*
* @since 3.0
*/
public static function addCustomItem($label, $link = 'javascript:void(0)', $linkAttributes = '', $className = '', $ajaxLoad = false,
$jsCallBackFunc = null)
{
static::start();
if ($ajaxLoad)
{
$href = ' href = "javascript:void(0)" onclick="loadAjax(\'' . $link . '\', \'' . $jsCallBackFunc . '\')"';
}
else
{
$href = ' href = "' . $link . '" ';
}
$dropDownList = static::$dropDownList;
$dropDownList .= '<li class="' . $className . '"><a ' . $linkAttributes . $href . ' >';
$dropDownList .= $label;
$dropDownList .= '</a></li>';
static::$dropDownList = $dropDownList;
return;
}
}

View File

@ -0,0 +1,129 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage HTML
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
/**
* Utility class for cloaking email addresses
*
* @package Joomla.Libraries
* @subpackage HTML
* @since 1.5
*/
abstract class JHtmlEmail
{
/**
* Simple JavaScript email cloaker
*
* By default replaces an email with a mailto link with email cloaked
*
* @param string $mail The -mail address to cloak.
* @param boolean $mailto True if text and mailing address differ
* @param string $text Text for the link
* @param boolean $email True if text is an e-mail address
*
* @return string The cloaked email.
*
* @since 1.5
*/
public static function cloak($mail, $mailto = true, $text = '', $email = true)
{
// Convert text
$mail = static::convertEncoding($mail);
// Split email by @ symbol
$mail = explode('@', $mail);
$mail_parts = explode('.', $mail[1]);
// Random number
$rand = rand(1, 100000);
$replacement = "\n <script type='text/javascript'>";
$replacement .= "\n <!--";
$replacement .= "\n var prefix = '&#109;a' + 'i&#108;' + '&#116;o';";
$replacement .= "\n var path = 'hr' + 'ef' + '=';";
$replacement .= "\n var addy" . $rand . " = '" . @$mail[0] . "' + '&#64;';";
$replacement .= "\n addy" . $rand . " = addy" . $rand . " + '" . implode("' + '&#46;' + '", $mail_parts) . "';";
if ($mailto)
{
// Special handling when mail text is different from mail address
if ($text)
{
if ($email)
{
// Convert text
$text = static::convertEncoding($text);
// Split email by @ symbol
$text = explode('@', $text);
$text_parts = explode('.', $text[1]);
$replacement .= "\n var addy_text" . $rand . " = '" . @$text[0] . "' + '&#64;' + '" . implode("' + '&#46;' + '", @$text_parts)
. "';";
}
else
{
$replacement .= "\n var addy_text" . $rand . " = '" . $text . "';";
}
$replacement .= "\n document.write('<a ' + path + '\'' + prefix + ':' + addy" . $rand . " + '\'>');";
$replacement .= "\n document.write(addy_text" . $rand . ");";
$replacement .= "\n document.write('<\/a>');";
}
else
{
$replacement .= "\n document.write('<a ' + path + '\'' + prefix + ':' + addy" . $rand . " + '\'>');";
$replacement .= "\n document.write(addy" . $rand . ");";
$replacement .= "\n document.write('<\/a>');";
}
}
else
{
$replacement .= "\n document.write(addy" . $rand . ");";
}
$replacement .= "\n //-->";
$replacement .= '\n </script>';
// XHTML compliance no Javascript text handling
$replacement .= "<script type='text/javascript'>";
$replacement .= "\n <!--";
$replacement .= "\n document.write('<span style=\'display: none;\'>');";
$replacement .= "\n //-->";
$replacement .= "\n </script>";
$replacement .= JText::_('JLIB_HTML_CLOAKING');
$replacement .= "\n <script type='text/javascript'>";
$replacement .= "\n <!--";
$replacement .= "\n document.write('</');";
$replacement .= "\n document.write('span>');";
$replacement .= "\n //-->";
$replacement .= "\n </script>";
return $replacement;
}
/**
* Convert encoded text
*
* @param string $text Text to convert
*
* @return string The converted text.
*
* @since 1.5
*/
protected static function convertEncoding($text)
{
// Replace vowels with character encoding
$text = str_replace('a', '&#97;', $text);
$text = str_replace('e', '&#101;', $text);
$text = str_replace('i', '&#105;', $text);
$text = str_replace('o', '&#111;', $text);
$text = str_replace('u', '&#117;', $text);
return $text;
}
}

View File

@ -0,0 +1,35 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage HTML
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
/**
* Utility class for form elements
*
* @package Joomla.Libraries
* @subpackage HTML
* @since 1.5
*/
abstract class JHtmlForm
{
/**
* Displays a hidden token field to reduce the risk of CSRF exploits
*
* Use in conjunction with JSession::checkToken
*
* @return string A hidden input field with a token
*
* @see JSession::checkToken
* @since 1.5
*/
public static function token()
{
return '<input type="hidden" name="' . JSession::getFormToken() . '" value="1" />';
}
}

View File

@ -0,0 +1,147 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage HTML
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
/**
* Utility class for form related behaviors
*
* @package Joomla.Libraries
* @subpackage HTML
* @since 3.0
*/
abstract class JHtmlFormbehavior
{
/**
* @var array Array containing information for loaded files
* @since 3.0
*/
protected static $loaded = array();
/**
* Method to load the Chosen JavaScript framework and supporting CSS into the document head
*
* If debugging mode is on an uncompressed version of Chosen is included for easier debugging.
*
* @param string $selector Class for Chosen elements.
* @param mixed $debug Is debugging mode on? [optional]
*
* @return void
*
* @since 3.0
*/
public static function chosen($selector = '.advancedSelect', $debug = null)
{
if (isset(static::$loaded[__METHOD__][$selector]))
{
return;
}
// Include jQuery
JHtml::_('jquery.framework');
// Add chosen.jquery.js language strings
JText::script('JGLOBAL_SELECT_SOME_OPTIONS');
JText::script('JGLOBAL_SELECT_AN_OPTION');
JText::script('JGLOBAL_SELECT_NO_RESULTS_MATCH');
// If no debugging value is set, use the configuration setting
if ($debug === null)
{
$config = JFactory::getConfig();
$debug = (boolean) $config->get('debug');
}
JHtml::_('script', 'jui/chosen.jquery.min.js', false, true, false, false, $debug);
JHtml::_('stylesheet', 'jui/chosen.css', false, true);
JFactory::getDocument()->addScriptDeclaration("
jQuery(document).ready(function (){
jQuery('" . $selector . "').chosen({
disable_search_threshold : 10,
allow_single_deselect : true
});
});
"
);
static::$loaded[__METHOD__][$selector] = true;
return;
}
/**
* Method to load the AJAX Chosen library
*
* If debugging mode is on an uncompressed version of AJAX Chosen is included for easier debugging.
*
* @param JRegistry $options Options in a JRegistry object
* @param mixed $debug Is debugging mode on? [optional]
*
* @return void
*
* @since 3.0
*/
public static function ajaxchosen(JRegistry $options, $debug = null)
{
// Retrieve options/defaults
$selector = $options->get('selector', '.tagfield');
$type = $options->get('type', 'GET');
$url = $options->get('url', null);
$dataType = $options->get('dataType', 'json');
$jsonTermKey = $options->get('jsonTermKey', 'term');
$afterTypeDelay = $options->get('afterTypeDelay', '500');
$minTermLength = $options->get('minTermLength', '3');
JText::script('JGLOBAL_KEEP_TYPING');
JText::script('JGLOBAL_LOOKING_FOR');
// Ajax URL is mandatory
if (!empty($url))
{
if (isset(static::$loaded[__METHOD__][$selector]))
{
return;
}
// Include jQuery
JHtml::_('jquery.framework');
// Requires chosen to work
static::chosen($selector, $debug);
JHtml::_('script', 'jui/ajax-chosen.min.js', false, true, false, false, $debug);
JFactory::getDocument()->addScriptDeclaration("
(function($){
$(document).ready(function () {
$('" . $selector . "').ajaxChosen({
type: '" . $type . "',
url: '" . $url . "',
dataType: '" . $dataType . "',
jsonTermKey: '" . $jsonTermKey . "',
afterTypeDelay: '" . $afterTypeDelay . "',
minTermLength: '" . $minTermLength . "'
}, function (data) {
var results = [];
$.each(data, function (i, val) {
results.push({ value: val.value, text: val.text });
});
return results;
});
});
})(jQuery);
"
);
static::$loaded[__METHOD__][$selector] = true;
}
return;
}
}

355
libraries/cms/html/grid.php Normal file
View File

@ -0,0 +1,355 @@
<?php
/**
* @package Joomla.Platform
* @subpackage HTML
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
/**
* Utility class for creating HTML Grids
*
* @package Joomla.Platform
* @subpackage HTML
* @since 1.5
*/
abstract class JHtmlGrid
{
/**
* Display a boolean setting widget.
*
* @param integer $i The row index.
* @param integer $value The value of the boolean field.
* @param string $taskOn Task to turn the boolean setting on.
* @param string $taskOff Task to turn the boolean setting off.
*
* @return string The boolean setting widget.
*
* @since 1.6
*/
public static function boolean($i, $value, $taskOn = null, $taskOff = null)
{
// Load the behavior.
static::behavior();
JHtml::_('bootstrap.tooltip');
// Build the title.
$title = ($value) ? JText::_('JYES') : JText::_('JNO');
$title = JHtml::tooltipText($title, JText::_('JGLOBAL_CLICK_TO_TOGGLE_STATE'), 0);
// Build the <a> tag.
$bool = ($value) ? 'true' : 'false';
$task = ($value) ? $taskOff : $taskOn;
$toggle = (!$task) ? false : true;
if ($toggle)
{
return '<a class="grid_' . $bool . ' hasToolip" title="' . $title . '" rel="{id:\'cb' . $i . '\', task:\'' . $task
. '\'}" href="#toggle"></a>';
}
else
{
return '<a class="grid_' . $bool . '"></a>';
}
}
/**
* Method to sort a column in a grid
*
* @param string $title The link title
* @param string $order The order field for the column
* @param string $direction The current direction
* @param string $selected The selected ordering
* @param string $task An optional task override
* @param string $new_direction An optional direction for the new column
* @param string $tip An optional text shown as tooltip title instead of $title
*
* @return string
*
* @since 1.5
*/
public static function sort($title, $order, $direction = 'asc', $selected = 0, $task = null, $new_direction = 'asc', $tip = '')
{
JHtml::_('bootstrap.tooltip');
$direction = strtolower($direction);
$icon = array('arrow-up-3', 'arrow-down-3');
$index = (int) ($direction == 'desc');
if ($order != $selected)
{
$direction = $new_direction;
}
else
{
$direction = ($direction == 'desc') ? 'asc' : 'desc';
}
$html = '<a href="#" onclick="Joomla.tableOrdering(\'' . $order . '\',\'' . $direction . '\',\'' . $task . '\');return false;"'
. ' class="hasTooltip" title="' . JHtml::tooltipText(($tip ? $tip : $title), 'JGLOBAL_CLICK_TO_SORT_THIS_COLUMN') . '">';
if (isset($title['0']) && $title['0'] == '<')
{
$html .= $title;
}
else
{
$html .= JText::_($title);
}
if ($order == $selected)
{
$html .= ' <i class="icon-' . $icon[$index] . '"></i>';
}
$html .= '</a>';
return $html;
}
/**
* Method to check all checkboxes in a grid
*
* @param string $name The name of the form element
* @param string $tip The text shown as tooltip title instead of $tip
* @param string $action The action to perform on clicking the checkbox
*
* @return string
*
* @since 3.1.2
*/
public static function checkall($name = 'checkall-toggle', $tip = 'JGLOBAL_CHECK_ALL', $action = 'Joomla.checkAll(this)')
{
JHtml::_('bootstrap.tooltip');
return '<input type="checkbox" name="' . $name . '" value="" class="hasTooltip" title="' . JHtml::tooltipText($tip) . '" onclick="' . $action . '" />';
}
/**
* Method to create a checkbox for a grid row.
*
* @param integer $rowNum The row index
* @param integer $recId The record id
* @param boolean $checkedOut True if item is checke out
* @param string $name The name of the form element
*
* @return mixed String of html with a checkbox if item is not checked out, null if checked out.
*
* @since 1.5
*/
public static function id($rowNum, $recId, $checkedOut = false, $name = 'cid')
{
return $checkedOut ? '' : '<input type="checkbox" id="cb' . $rowNum . '" name="' . $name . '[]" value="' . $recId
. '" onclick="Joomla.isChecked(this.checked);" />';
}
/**
* Displays a checked out icon.
*
* @param object &$row A data object (must contain checkedout as a property).
* @param integer $i The index of the row.
* @param string $identifier The property name of the primary key or index of the row.
*
* @return string
*
* @since 1.5
*/
public static function checkedOut(&$row, $i, $identifier = 'id')
{
$user = JFactory::getUser();
$userid = $user->get('id');
if ($row instanceof JTable)
{
$result = $row->isCheckedOut($userid);
}
else
{
$result = false;
}
if ($result)
{
return static::_checkedOut($row);
}
else
{
if ($identifier == 'id')
{
return JHtml::_('grid.id', $i, $row->$identifier);
}
else
{
return JHtml::_('grid.id', $i, $row->$identifier, $result, $identifier);
}
}
}
/**
* Method to create a clickable icon to change the state of an item
*
* @param mixed $value Either the scalar value or an object (for backward compatibility, deprecated)
* @param integer $i The index
* @param string $img1 Image for a positive or on value
* @param string $img0 Image for the empty or off value
* @param string $prefix An optional prefix for the task
*
* @return string
*
* @since 1.5
*/
public static function published($value, $i, $img1 = 'tick.png', $img0 = 'publish_x.png', $prefix = '')
{
if (is_object($value))
{
$value = $value->published;
}
$img = $value ? $img1 : $img0;
$task = $value ? 'unpublish' : 'publish';
$alt = $value ? JText::_('JPUBLISHED') : JText::_('JUNPUBLISHED');
$action = $value ? JText::_('JLIB_HTML_UNPUBLISH_ITEM') : JText::_('JLIB_HTML_PUBLISH_ITEM');
return '<a href="#" onclick="return listItemTask(\'cb' . $i . '\',\'' . $prefix . $task . '\')" title="' . $action . '">'
. JHtml::_('image', 'admin/' . $img, $alt, null, true) . '</a>';
}
/**
* Method to create a select list of states for filtering
* By default the filter shows only published and unpublished items
*
* @param string $filter_state The initial filter state
* @param string $published The JText string for published
* @param string $unpublished The JText string for Unpublished
* @param string $archived The JText string for Archived
* @param string $trashed The JText string for Trashed
*
* @return string
*
* @since 1.5
*/
public static function state($filter_state = '*', $published = 'Published', $unpublished = 'Unpublished', $archived = null, $trashed = null)
{
$state = array('' => '- ' . JText::_('JLIB_HTML_SELECT_STATE') . ' -', 'P' => JText::_($published), 'U' => JText::_($unpublished));
if ($archived)
{
$state['A'] = JText::_($archived);
}
if ($trashed)
{
$state['T'] = JText::_($trashed);
}
return JHtml::_(
'select.genericlist',
$state,
'filter_state',
array(
'list.attr' => 'class="inputbox" size="1" onchange="Joomla.submitform();"',
'list.select' => $filter_state,
'option.key' => null
)
);
}
/**
* Method to create an icon for saving a new ordering in a grid
*
* @param array $rows The array of rows of rows
* @param string $image The image [UNUSED]
* @param string $task The task to use, defaults to save order
*
* @return string
*
* @since 1.5
*/
public static function order($rows, $image = 'filesave.png', $task = 'saveorder')
{
return '<a href="javascript:saveorder(' . (count($rows) - 1) . ', \'' . $task . '\')" rel="tooltip" class="saveorder btn btn-micro pull-right" title="'
. JText::_('JLIB_HTML_SAVE_ORDER') . '"><i class="icon-menu-2"></i></a>';
}
/**
* Method to create a checked out icon with optional overlib in a grid.
*
* @param object &$row The row object
* @param boolean $overlib True if an overlib with checkout information should be created.
*
* @return string HTMl for the icon and overlib
*
* @since 1.5
*/
protected static function _checkedOut(&$row, $overlib = true)
{
$hover = '';
if ($overlib)
{
JHtml::_('bootstrap.tooltip');
$date = JHtml::_('date', $row->checked_out_time, JText::_('DATE_FORMAT_LC1'));
$time = JHtml::_('date', $row->checked_out_time, 'H:i');
$hover = '<span class="editlinktip hasTooltip" title="' . JHtml::tooltipText('JLIB_HTML_CHECKED_OUT', $row->editor) . '<br />' . $date . '<br />'
. $time . '">';
}
return $hover . JHtml::_('image', 'admin/checked_out.png', null, null, true) . '</span>';
}
/**
* Method to build the behavior script and add it to the document head.
*
* @return void
*
* @since 1.6
*/
public static function behavior()
{
static $loaded;
if (!$loaded)
{
// Build the behavior script.
$js = '
window.addEvent(\'domready\', function(){
actions = $$(\'a.move_up\');
actions.combine($$(\'a.move_down\'));
actions.combine($$(\'a.grid_true\'));
actions.combine($$(\'a.grid_false\'));
actions.combine($$(\'a.grid_trash\'));
actions.each(function(a){
a.addEvent(\'click\', function(){
args = JSON.decode(this.rel);
listItemTask(args.id, args.task);
});
});
$$(\'input.check-all-toggle\').each(function(el){
el.addEvent(\'click\', function(){
if (el.checked) {
document.id(this.form).getElements(\'input[type=checkbox]\').each(function(i){
i.checked = true;
})
}
else {
document.id(this.form).getElements(\'input[type=checkbox]\').each(function(i){
i.checked = false;
})
}
});
});
});';
// Add the behavior to the document head.
$document = JFactory::getDocument();
$document->addScriptDeclaration($js);
$loaded = true;
}
}
}

1093
libraries/cms/html/html.php Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,80 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage HTML
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('JPATH_BASE') or die;
/**
* Utility class for icons.
*
* @package Joomla.Libraries
* @subpackage HTML
* @since 2.5
*/
abstract class JHtmlIcons
{
/**
* Method to generate html code for a list of buttons
*
* @param array $buttons Array of buttons
*
* @return string
*
* @since 2.5
*/
public static function buttons($buttons)
{
$html = array();
foreach ($buttons as $button)
{
$html[] = JHtml::_('icons.button', $button);
}
return implode($html);
}
/**
* Method to generate html code for a list of buttons
*
* @param array $button Button properties
*
* @return string
*
* @since 2.5
*/
public static function button($button)
{
if (isset($button['access']))
{
if (is_bool($button['access']))
{
if ($button['access'] == false)
{
return '';
}
}
else
{
// Get the user object to verify permissions
$user = JFactory::getUser();
// Take each pair of permission, context values.
for ($i = 0, $n = count($button['access']); $i < $n; $i += 2)
{
if (!$user->authorise($button['access'][$i], $button['access'][$i + 1]))
{
return '';
}
}
}
}
// Instantiate a new JLayoutFile instance and render the layout
$layout = new JLayoutFile('joomla.quickicons.icon');
return $layout->render($button);
}
}

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1,403 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage HTML
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
/**
* Utility class for creating HTML Grids
*
* @package Joomla.Libraries
* @subpackage HTML
* @since 1.6
*/
abstract class JHtmlJGrid
{
/**
* Returns an action on a grid
*
* @param integer $i The row index
* @param string $task The task to fire
* @param string|array $prefix An optional task prefix or an array of options
* @param string $text An optional text to display [unused - @deprecated 4.0]
* @param string $active_title An optional active tooltip to display if $enable is true
* @param string $inactive_title An optional inactive tooltip to display if $enable is true
* @param boolean $tip An optional setting for tooltip
* @param string $active_class An optional active HTML class
* @param string $inactive_class An optional inactive HTML class
* @param boolean $enabled An optional setting for access control on the action.
* @param boolean $translate An optional setting for translation.
* @param string $checkbox An optional prefix for checkboxes.
*
* @return string The HTML markup
*
* @since 1.6
*/
public static function action($i, $task, $prefix = '', $text = '', $active_title = '', $inactive_title = '', $tip = false, $active_class = '',
$inactive_class = '', $enabled = true, $translate = true, $checkbox = 'cb')
{
if (is_array($prefix))
{
$options = $prefix;
$active_title = array_key_exists('active_title', $options) ? $options['active_title'] : $active_title;
$inactive_title = array_key_exists('inactive_title', $options) ? $options['inactive_title'] : $inactive_title;
$tip = array_key_exists('tip', $options) ? $options['tip'] : $tip;
$active_class = array_key_exists('active_class', $options) ? $options['active_class'] : $active_class;
$inactive_class = array_key_exists('inactive_class', $options) ? $options['inactive_class'] : $inactive_class;
$enabled = array_key_exists('enabled', $options) ? $options['enabled'] : $enabled;
$translate = array_key_exists('translate', $options) ? $options['translate'] : $translate;
$checkbox = array_key_exists('checkbox', $options) ? $options['checkbox'] : $checkbox;
$prefix = array_key_exists('prefix', $options) ? $options['prefix'] : '';
}
if ($tip)
{
JHtml::_('bootstrap.tooltip');
$title = $enabled ? $active_title : $inactive_title;
$title = $translate ? JText::_($title) : $title;
$title = JHtml::tooltipText($title, '', 0);
}
if ($enabled)
{
$html[] = '<a class="btn btn-micro ' . ($active_class == "publish" ? 'active' : '') . ' ' . ($tip ? 'hasTooltip"' : '') . '"';
$html[] = ' href="javascript:void(0);" onclick="return listItemTask(\'' . $checkbox . $i . '\',\'' . $prefix . $task . '\')"';
$html[] = $tip ? ' title="' . $title . '"' : '';
$html[] = '>';
$html[] = '<i class="icon-' . $active_class . '">';
$html[] = '</i>';
$html[] = '</a>';
}
else
{
$html[] = '<a class="btn btn-micro disabled jgrid ' . ($tip ? 'hasTooltip"' : '') . '"';
$html[] = $tip ? ' title="' . $title . '"' : '';
$html[] = '>';
if ($active_class == "protected")
{
$html[] = '<i class="icon-lock"></i>';
}
else
{
$html[] = '<i class="icon-' . $inactive_class . '"></i>';
}
$html[] = '</a>';
}
return implode($html);
}
/**
* Returns a state on a grid
*
* @param array $states array of value/state. Each state is an array of the form
* (task, text, title,html active class, HTML inactive class)
* or ('task'=>task, 'text'=>text, 'active_title'=>active title,
* 'inactive_title'=>inactive title, 'tip'=>boolean, 'active_class'=>html active class,
* 'inactive_class'=>html inactive class)
* @param integer $value The state value.
* @param integer $i The row index
* @param string|array $prefix An optional task prefix or an array of options
* @param boolean $enabled An optional setting for access control on the action.
* @param boolean $translate An optional setting for translation.
* @param string $checkbox An optional prefix for checkboxes.
*
* @return string The HTML markup
*
* @since 1.6
*/
public static function state($states, $value, $i, $prefix = '', $enabled = true, $translate = true, $checkbox = 'cb')
{
if (is_array($prefix))
{
$options = $prefix;
$enabled = array_key_exists('enabled', $options) ? $options['enabled'] : $enabled;
$translate = array_key_exists('translate', $options) ? $options['translate'] : $translate;
$checkbox = array_key_exists('checkbox', $options) ? $options['checkbox'] : $checkbox;
$prefix = array_key_exists('prefix', $options) ? $options['prefix'] : '';
}
$state = JArrayHelper::getValue($states, (int) $value, $states[0]);
$task = array_key_exists('task', $state) ? $state['task'] : $state[0];
$text = array_key_exists('text', $state) ? $state['text'] : (array_key_exists(1, $state) ? $state[1] : '');
$active_title = array_key_exists('active_title', $state) ? $state['active_title'] : (array_key_exists(2, $state) ? $state[2] : '');
$inactive_title = array_key_exists('inactive_title', $state) ? $state['inactive_title'] : (array_key_exists(3, $state) ? $state[3] : '');
$tip = array_key_exists('tip', $state) ? $state['tip'] : (array_key_exists(4, $state) ? $state[4] : false);
$active_class = array_key_exists('active_class', $state) ? $state['active_class'] : (array_key_exists(5, $state) ? $state[5] : '');
$inactive_class = array_key_exists('inactive_class', $state) ? $state['inactive_class'] : (array_key_exists(6, $state) ? $state[6] : '');
return static::action(
$i, $task, $prefix, $text, $active_title, $inactive_title, $tip,
$active_class, $inactive_class, $enabled, $translate, $checkbox
);
}
/**
* Returns a published state on a grid
*
* @param integer $value The state value.
* @param integer $i The row index
* @param string|array $prefix An optional task prefix or an array of options
* @param boolean $enabled An optional setting for access control on the action.
* @param string $checkbox An optional prefix for checkboxes.
* @param string $publish_up An optional start publishing date.
* @param string $publish_down An optional finish publishing date.
*
* @return string The HTML markup
*
* @see JHtmlJGrid::state
* @since 1.6
*/
public static function published($value, $i, $prefix = '', $enabled = true, $checkbox = 'cb', $publish_up = null, $publish_down = null)
{
if (is_array($prefix))
{
$options = $prefix;
$enabled = array_key_exists('enabled', $options) ? $options['enabled'] : $enabled;
$checkbox = array_key_exists('checkbox', $options) ? $options['checkbox'] : $checkbox;
$prefix = array_key_exists('prefix', $options) ? $options['prefix'] : '';
}
$states = array(1 => array('unpublish', 'JPUBLISHED', 'JLIB_HTML_UNPUBLISH_ITEM', 'JPUBLISHED', true, 'publish', 'publish'),
0 => array('publish', 'JUNPUBLISHED', 'JLIB_HTML_PUBLISH_ITEM', 'JUNPUBLISHED', true, 'unpublish', 'unpublish'),
2 => array('unpublish', 'JARCHIVED', 'JLIB_HTML_UNPUBLISH_ITEM', 'JARCHIVED', true, 'archive', 'archive'),
-2 => array('publish', 'JTRASHED', 'JLIB_HTML_PUBLISH_ITEM', 'JTRASHED', true, 'trash', 'trash'));
// Special state for dates
if ($publish_up || $publish_down)
{
$nullDate = JFactory::getDbo()->getNullDate();
$nowDate = JFactory::getDate()->toUnix();
$tz = new DateTimeZone(JFactory::getUser()->getParam('timezone', JFactory::getConfig()->get('offset')));
$publish_up = ($publish_up != $nullDate) ? JFactory::getDate($publish_up, 'UTC')->setTimeZone($tz) : false;
$publish_down = ($publish_down != $nullDate) ? JFactory::getDate($publish_down, 'UTC')->setTimeZone($tz) : false;
// Create tip text, only we have publish up or down settings
$tips = array();
if ($publish_up)
{
$tips[] = JText::sprintf('JLIB_HTML_PUBLISHED_START', $publish_up->format(JDate::$format, true));
}
if ($publish_down)
{
$tips[] = JText::sprintf('JLIB_HTML_PUBLISHED_FINISHED', $publish_down->format(JDate::$format, true));
}
$tip = empty($tips) ? false : implode('<br/>', $tips);
// Add tips and special titles
foreach ($states as $key => $state)
{
// Create special titles for published items
if ($key == 1)
{
$states[$key][2] = $states[$key][3] = 'JLIB_HTML_PUBLISHED_ITEM';
if ($publish_up > $nullDate && $nowDate < $publish_up->toUnix())
{
$states[$key][2] = $states[$key][3] = 'JLIB_HTML_PUBLISHED_PENDING_ITEM';
$states[$key][5] = $states[$key][6] = 'pending';
}
if ($publish_down > $nullDate && $nowDate > $publish_down->toUnix())
{
$states[$key][2] = $states[$key][3] = 'JLIB_HTML_PUBLISHED_EXPIRED_ITEM';
$states[$key][5] = $states[$key][6] = 'expired';
}
}
// Add tips to titles
if ($tip)
{
$states[$key][1] = JText::_($states[$key][1]);
$states[$key][2] = JText::_($states[$key][2]) . '<br />' . $tip;
$states[$key][3] = JText::_($states[$key][3]) . '<br />' . $tip;
$states[$key][4] = true;
}
}
return static::state($states, $value, $i, array('prefix' => $prefix, 'translate' => !$tip), $enabled, true, $checkbox);
}
return static::state($states, $value, $i, $prefix, $enabled, true, $checkbox);
}
/**
* Returns a isDefault state on a grid
*
* @param integer $value The state value.
* @param integer $i The row index
* @param string|array $prefix An optional task prefix or an array of options
* @param boolean $enabled An optional setting for access control on the action.
* @param string $checkbox An optional prefix for checkboxes.
*
* @return string The HTML markup
*
* @see JHtmlJGrid::state
* @since 1.6
*/
public static function isdefault($value, $i, $prefix = '', $enabled = true, $checkbox = 'cb')
{
if (is_array($prefix))
{
$options = $prefix;
$enabled = array_key_exists('enabled', $options) ? $options['enabled'] : $enabled;
$checkbox = array_key_exists('checkbox', $options) ? $options['checkbox'] : $checkbox;
$prefix = array_key_exists('prefix', $options) ? $options['prefix'] : '';
}
$states = array(
0 => array('setDefault', '', 'JLIB_HTML_SETDEFAULT_ITEM', '', 1, 'unfeatured', 'unfeatured'),
1 => array('unsetDefault', 'JDEFAULT', 'JLIB_HTML_UNSETDEFAULT_ITEM', 'JDEFAULT', 1, 'featured', 'featured'),
);
return static::state($states, $value, $i, $prefix, $enabled, true, $checkbox);
}
/**
* Returns an array of standard published state filter options.
*
* @param array $config An array of configuration options.
* This array can contain a list of key/value pairs where values are boolean
* and keys can be taken from 'published', 'unpublished', 'archived', 'trash', 'all'.
* These pairs determine which values are displayed.
*
* @return string The HTML markup
*
* @since 1.6
*/
public static function publishedOptions($config = array())
{
// Build the active state filter options.
$options = array();
if (!array_key_exists('published', $config) || $config['published'])
{
$options[] = JHtml::_('select.option', '1', 'JPUBLISHED');
}
if (!array_key_exists('unpublished', $config) || $config['unpublished'])
{
$options[] = JHtml::_('select.option', '0', 'JUNPUBLISHED');
}
if (!array_key_exists('archived', $config) || $config['archived'])
{
$options[] = JHtml::_('select.option', '2', 'JARCHIVED');
}
if (!array_key_exists('trash', $config) || $config['trash'])
{
$options[] = JHtml::_('select.option', '-2', 'JTRASHED');
}
if (!array_key_exists('all', $config) || $config['all'])
{
$options[] = JHtml::_('select.option', '*', 'JALL');
}
return $options;
}
/**
* Returns a checked-out icon
*
* @param integer $i The row index.
* @param string $editorName The name of the editor.
* @param string $time The time that the object was checked out.
* @param string|array $prefix An optional task prefix or an array of options
* @param boolean $enabled True to enable the action.
* @param string $checkbox An optional prefix for checkboxes.
*
* @return string The HTML markup
*
* @since 1.6
*/
public static function checkedout($i, $editorName, $time, $prefix = '', $enabled = false, $checkbox = 'cb')
{
JHtml::_('bootstrap.tooltip');
if (is_array($prefix))
{
$options = $prefix;
$enabled = array_key_exists('enabled', $options) ? $options['enabled'] : $enabled;
$checkbox = array_key_exists('checkbox', $options) ? $options['checkbox'] : $checkbox;
$prefix = array_key_exists('prefix', $options) ? $options['prefix'] : '';
}
$text = $editorName . '<br />' . JHtml::_('date', $time, JText::_('DATE_FORMAT_LC')) . '<br />' . JHtml::_('date', $time, 'H:i');
$active_title = JHtml::tooltipText(JText::_('JLIB_HTML_CHECKIN'), $text, 0);
$inactive_title = JHtml::tooltipText(JText::_('JLIB_HTML_CHECKED_OUT'), $text, 0);
return static::action(
$i, 'checkin', $prefix, JText::_('JLIB_HTML_CHECKED_OUT'), $active_title, $inactive_title, true, 'checkedout',
'checkedout', $enabled, false, $checkbox
);
}
/**
* Creates a order-up action icon.
*
* @param integer $i The row index.
* @param string $task An optional task to fire.
* @param string|array $prefix An optional task prefix or an array of options
* @param string $text An optional text to display
* @param boolean $enabled An optional setting for access control on the action.
* @param string $checkbox An optional prefix for checkboxes.
*
* @return string The HTML markup
*
* @since 1.6
*/
public static function orderUp($i, $task = 'orderup', $prefix = '', $text = 'JLIB_HTML_MOVE_UP', $enabled = true, $checkbox = 'cb')
{
if (is_array($prefix))
{
$options = $prefix;
$text = array_key_exists('text', $options) ? $options['text'] : $text;
$enabled = array_key_exists('enabled', $options) ? $options['enabled'] : $enabled;
$checkbox = array_key_exists('checkbox', $options) ? $options['checkbox'] : $checkbox;
$prefix = array_key_exists('prefix', $options) ? $options['prefix'] : '';
}
return static::action($i, $task, $prefix, $text, $text, $text, false, 'uparrow', 'uparrow_disabled', $enabled, true, $checkbox);
}
/**
* Creates a order-down action icon.
*
* @param integer $i The row index.
* @param string $task An optional task to fire.
* @param string|array $prefix An optional task prefix or an array of options
* @param string $text An optional text to display
* @param boolean $enabled An optional setting for access control on the action.
* @param string $checkbox An optional prefix for checkboxes.
*
* @return string The HTML markup
*
* @since 1.6
*/
public static function orderDown($i, $task = 'orderdown', $prefix = '', $text = 'JLIB_HTML_MOVE_DOWN', $enabled = true, $checkbox = 'cb')
{
if (is_array($prefix))
{
$options = $prefix;
$text = array_key_exists('text', $options) ? $options['text'] : $text;
$enabled = array_key_exists('enabled', $options) ? $options['enabled'] : $enabled;
$checkbox = array_key_exists('checkbox', $options) ? $options['checkbox'] : $checkbox;
$prefix = array_key_exists('prefix', $options) ? $options['prefix'] : '';
}
return static::action($i, $task, $prefix, $text, $text, $text, false, 'downarrow', 'downarrow_disabled', $enabled, true, $checkbox);
}
}

View File

@ -0,0 +1,107 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage HTML
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
/**
* Utility class for jQuery JavaScript behaviors
*
* @package Joomla.Libraries
* @subpackage HTML
* @since 3.0
*/
abstract class JHtmlJquery
{
/**
* @var array Array containing information for loaded files
* @since 3.0
*/
protected static $loaded = array();
/**
* Method to load the jQuery JavaScript framework into the document head
*
* If debugging mode is on an uncompressed version of jQuery is included for easier debugging.
*
* @param boolean $noConflict True to load jQuery in noConflict mode [optional]
* @param mixed $debug Is debugging mode on? [optional]
*
* @return void
*
* @since 3.0
*/
public static function framework($noConflict = true, $debug = null)
{
// Only load once
if (!empty(static::$loaded[__METHOD__]))
{
return;
}
// If no debugging value is set, use the configuration setting
if ($debug === null)
{
$config = JFactory::getConfig();
$debug = (boolean) $config->get('debug');
}
JHtml::_('script', 'jui/jquery.min.js', false, true, false, false, $debug);
// Check if we are loading in noConflict
if ($noConflict)
{
JHtml::_('script', 'jui/jquery-noconflict.js', false, true, false, false, false);
}
static::$loaded[__METHOD__] = true;
return;
}
/**
* Method to load the jQuery UI JavaScript framework into the document head
*
* If debugging mode is on an uncompressed version of jQuery UI is included for easier debugging.
*
* @param array $components The jQuery UI components to load [optional]
* @param mixed $debug Is debugging mode on? [optional]
*
* @return void
*
* @since 3.0
*/
public static function ui(array $components = array('core'), $debug = null)
{
// Set an array containing the supported jQuery UI components handled by this method
$supported = array('core', 'sortable');
// Include jQuery
static::framework();
// If no debugging value is set, use the configuration setting
if ($debug === null)
{
$config = JFactory::getConfig();
$debug = (boolean) $config->get('debug');
}
// Load each of the requested components
foreach ($components as $component)
{
// Only attempt to load the component if it's supported in core and hasn't already been loaded
if (in_array($component, $supported) && empty(static::$loaded[__METHOD__][$component]))
{
JHtml::_('script', 'jui/jquery.ui.' . $component . '.min.js', false, true, false, false, $debug);
static::$loaded[__METHOD__][$component] = true;
}
}
return;
}
}

View File

@ -0,0 +1,18 @@
; Joomla! Project
; Copyright (C) 2005 - 2013 Open Source Matters. All rights reserved.
; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php
; Note : All ini files need to be saved as UTF-8 - No BOM
JLIB_HTML_DATE_RELATIVE_DAYS="%s days ago"
JLIB_HTML_DATE_RELATIVE_DAYS_1="%s day ago"
JLIB_HTML_DATE_RELATIVE_DAYS_0="%s days ago"
JLIB_HTML_DATE_RELATIVE_HOURS="%s hours ago"
JLIB_HTML_DATE_RELATIVE_HOURS_1="%s hour ago"
JLIB_HTML_DATE_RELATIVE_HOURS_0="%s hours ago"
JLIB_HTML_DATE_RELATIVE_LESSTHANAMINUTE="Less than a minute ago"
JLIB_HTML_DATE_RELATIVE_MINUTES="%s minutes ago"
JLIB_HTML_DATE_RELATIVE_MINUTES_1="%s minute ago"
JLIB_HTML_DATE_RELATIVE_MINUTES_0="%s minutes ago"
JLIB_HTML_DATE_RELATIVE_WEEKS="%s weeks ago"
JLIB_HTML_DATE_RELATIVE_WEEKS_1="%s week ago"
JLIB_HTML_DATE_RELATIVE_WEEKS_0="%s weeks ago"

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

270
libraries/cms/html/list.php Normal file
View File

@ -0,0 +1,270 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage HTML
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
/**
* Utility class for creating different select lists
*
* @package Joomla.Libraries
* @subpackage HTML
* @since 1.5
*/
abstract class JHtmlList
{
/**
* Build the select list to choose an image
*
* @param string $name The name of the field
* @param string $active The selected item
* @param string $javascript Alternative javascript
* @param string $directory Directory the images are stored in
* @param string $extensions Allowed extensions
*
* @return array Image names
*
* @since 1.5
*/
public static function images($name, $active = null, $javascript = null, $directory = null, $extensions = "bmp|gif|jpg|png")
{
if (!$directory)
{
$directory = '/images/';
}
if (!$javascript)
{
$javascript = "onchange=\"if (document.forms.adminForm." . $name
. ".options[selectedIndex].value!='') {document.imagelib.src='..$directory' + document.forms.adminForm." . $name
. ".options[selectedIndex].value} else {document.imagelib.src='media/system/images/blank.png'}\"";
}
$imageFiles = new DirectoryIterator(JPATH_SITE . '/' . $directory);
$images = array(JHtml::_('select.option', '', JText::_('JOPTION_SELECT_IMAGE')));
foreach ($imageFiles as $file)
{
$fileName = $file->getFilename();
if (!$file->isFile())
{
continue;
}
if (preg_match('#(' . $extensions . ')$#', $fileName))
{
$images[] = JHtml::_('select.option', $fileName);
}
}
$images = JHtml::_(
'select.genericlist',
$images,
$name,
array(
'list.attr' => 'class="inputbox" size="1" ' . $javascript,
'list.select' => $active
)
);
return $images;
}
/**
* Returns an array of options
*
* @param string $query SQL with 'ordering' AS value and 'name field' AS text
* @param integer $chop The length of the truncated headline
*
* @return array An array of objects formatted for JHtml list processing
*
* @since 1.5
*/
public static function genericordering($query, $chop = 30)
{
$db = JFactory::getDbo();
$options = array();
$db->setQuery($query);
$items = $db->loadObjectList();
if (empty($items))
{
$options[] = JHtml::_('select.option', 1, JText::_('JOPTION_ORDER_FIRST'));
return $options;
}
$options[] = JHtml::_('select.option', 0, '0 ' . JText::_('JOPTION_ORDER_FIRST'));
for ($i = 0, $n = count($items); $i < $n; $i++)
{
$items[$i]->text = JText::_($items[$i]->text);
if (JString::strlen($items[$i]->text) > $chop)
{
$text = JString::substr($items[$i]->text, 0, $chop) . "...";
}
else
{
$text = $items[$i]->text;
}
$options[] = JHtml::_('select.option', $items[$i]->value, $items[$i]->value . '. ' . $text);
}
$options[] = JHtml::_('select.option', $items[$i - 1]->value + 1, ($items[$i - 1]->value + 1) . ' ' . JText::_('JOPTION_ORDER_LAST'));
return $options;
}
/**
* Build the select list for Ordering derived from a query
*
* @param integer $name The scalar value
* @param string $query The query
* @param string $attribs HTML tag attributes
* @param string $selected The selected item
* @param integer $neworder 1 if new and first, -1 if new and last, 0 or null if existing item
*
* @return string HTML markup for the select list
*
* @since 1.6
*/
public static function ordering($name, $query, $attribs = null, $selected = null, $neworder = null)
{
if (empty($attribs))
{
$attribs = 'class="inputbox" size="1"';
}
if (empty($neworder))
{
$orders = JHtml::_('list.genericordering', $query);
$html = JHtml::_('select.genericlist', $orders, $name, array('list.attr' => $attribs, 'list.select' => (int) $selected));
}
else
{
if ($neworder > 0)
{
$text = JText::_('JGLOBAL_NEWITEMSLAST_DESC');
}
elseif ($neworder <= 0)
{
$text = JText::_('JGLOBAL_NEWITEMSFIRST_DESC');
}
$html = '<input type="hidden" name="' . $name . '" value="' . (int) $selected . '" /><span class="readonly">' . $text . '</span>';
}
return $html;
}
/**
* Select list of active users
*
* @param string $name The name of the field
* @param string $active The active user
* @param integer $nouser If set include an option to select no user
* @param string $javascript Custom javascript
* @param string $order Specify a field to order by
*
* @return string The HTML for a list of users list of users
*
* @since 1.5
*/
public static function users($name, $active, $nouser = 0, $javascript = null, $order = 'name')
{
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select('u.id AS value, u.name AS text')
->from('#__users AS u')
->join('LEFT', '#__user_usergroup_map AS m ON m.user_id = u.id')
->where('u.block = 0')
->order($order)
->group('u.id');
$db->setQuery($query);
if ($nouser)
{
$users[] = JHtml::_('select.option', '0', JText::_('JOPTION_NO_USER'));
$users = array_merge($users, $db->loadObjectList());
}
else
{
$users = $db->loadObjectList();
}
$users = JHtml::_(
'select.genericlist',
$users,
$name,
array(
'list.attr' => 'class="inputbox" size="1" ' . $javascript,
'list.select' => $active
)
);
return $users;
}
/**
* Select list of positions - generally used for location of images
*
* @param string $name Name of the field
* @param string $active The active value
* @param string $javascript Alternative javascript
* @param boolean $none Null if not assigned
* @param boolean $center Null if not assigned
* @param boolean $left Null if not assigned
* @param boolean $right Null if not assigned
* @param boolean $id Null if not assigned
*
* @return array The positions
*
* @since 1.5
*/
public static function positions($name, $active = null, $javascript = null, $none = true, $center = true, $left = true, $right = true,
$id = false)
{
$pos = array();
if ($none)
{
$pos[''] = JText::_('JNONE');
}
if ($center)
{
$pos['center'] = JText::_('JGLOBAL_CENTER');
}
if ($left)
{
$pos['left'] = JText::_('JGLOBAL_LEFT');
}
if ($right)
{
$pos['right'] = JText::_('JGLOBAL_RIGHT');
}
$positions = JHtml::_(
'select.genericlist', $pos, $name,
array(
'id' => $id,
'list.attr' => 'class="inputbox" size="1"' . $javascript,
'list.select' => $active,
'option.key' => null,
)
);
return $positions;
}
}

357
libraries/cms/html/menu.php Normal file
View File

@ -0,0 +1,357 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage HTML
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
/**
* Utility class working with menu select lists
*
* @package Joomla.Libraries
* @subpackage HTML
* @since 1.5
*/
abstract class JHtmlMenu
{
/**
* Cached array of the menus.
*
* @var array
* @since 1.6
*/
protected static $menus = null;
/**
* Cached array of the menus items.
*
* @var array
* @since 1.6
*/
protected static $items = null;
/**
* Get a list of the available menus.
*
* @return string
*
* @since 1.6
*/
public static function menus()
{
if (empty(static::$menus))
{
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select('menutype AS value, title AS text')
->from($db->quoteName('#__menu_types'))
->order('title');
$db->setQuery($query);
static::$menus = $db->loadObjectList();
}
return static::$menus;
}
/**
* Returns an array of menu items grouped by menu.
*
* @param array $config An array of configuration options.
*
* @return array
*
* @since 1.6
*/
public static function menuitems($config = array())
{
if (empty(static::$items))
{
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select('menutype AS value, title AS text')
->from($db->quoteName('#__menu_types'))
->order('title');
$db->setQuery($query);
$menus = $db->loadObjectList();
$query->clear()
->select('a.id AS value, a.title AS text, a.level, a.menutype')
->from('#__menu AS a')
->where('a.parent_id > 0')
->where('a.type <> ' . $db->quote('url'))
->where('a.client_id = 0');
// Filter on the published state
if (isset($config['published']))
{
if (is_numeric($config['published']))
{
$query->where('a.published = ' . (int) $config['published']);
}
elseif ($config['published'] === '')
{
$query->where('a.published IN (0,1)');
}
}
$query->order('a.lft');
$db->setQuery($query);
$items = $db->loadObjectList();
// Collate menu items based on menutype
$lookup = array();
foreach ($items as &$item)
{
if (!isset($lookup[$item->menutype]))
{
$lookup[$item->menutype] = array();
}
$lookup[$item->menutype][] = &$item;
$item->text = str_repeat('- ', $item->level) . $item->text;
}
static::$items = array();
foreach ($menus as &$menu)
{
// Start group:
static::$items[] = JHtml::_('select.optgroup', $menu->text);
// Special "Add to this Menu" option:
static::$items[] = JHtml::_('select.option', $menu->value . '.1', JText::_('JLIB_HTML_ADD_TO_THIS_MENU'));
// Menu items:
if (isset($lookup[$menu->value]))
{
foreach ($lookup[$menu->value] as &$item)
{
static::$items[] = JHtml::_('select.option', $menu->value . '.' . $item->value, $item->text);
}
}
// Finish group:
static::$items[] = JHtml::_('select.optgroup', $menu->text);
}
}
return static::$items;
}
/**
* Displays an HTML select list of menu items.
*
* @param string $name The name of the control.
* @param string $selected The value of the selected option.
* @param string $attribs Attributes for the control.
* @param array $config An array of options for the control.
*
* @return string
*
* @since 1.6
*/
public static function menuitemlist($name, $selected = null, $attribs = null, $config = array())
{
static $count;
$options = static::menuitems($config);
return JHtml::_(
'select.genericlist', $options, $name,
array(
'id' => isset($config['id']) ? $config['id'] : 'assetgroups_' . (++$count),
'list.attr' => (is_null($attribs) ? 'class="inputbox" size="1"' : $attribs),
'list.select' => (int) $selected,
'list.translate' => false
)
);
}
/**
* Build the select list for Menu Ordering
*
* @param object &$row The row object
* @param integer $id The id for the row. Must exist to enable menu ordering
*
* @return string
*
* @since 1.5
*/
public static function ordering(&$row, $id)
{
if ($id)
{
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select('ordering AS value, title AS text')
->from($db->quoteName('#__menu'))
->where($db->quoteName('menutype') . ' = ' . $db->quote($row->menutype))
->where($db->quoteName('parent_id') . ' = ' . (int) $row->parent_id)
->where($db->quoteName('published') . ' != -2')
->order('ordering');
$order = JHtml::_('list.genericordering', $query);
$ordering = JHtml::_(
'select.genericlist', $order, 'ordering',
array('list.attr' => 'class="inputbox" size="1"', 'list.select' => (int) $row->ordering)
);
}
else
{
$ordering = '<input type="hidden" name="ordering" value="' . $row->ordering . '" />' . JText::_('JGLOBAL_NEWITEMSLAST_DESC');
}
return $ordering;
}
/**
* Build the multiple select list for Menu Links/Pages
*
* @param boolean $all True if all can be selected
* @param boolean $unassigned True if unassigned can be selected
*
* @return string
*
* @since 1.5
*/
public static function linkoptions($all = false, $unassigned = false)
{
$db = JFactory::getDbo();
// Get a list of the menu items
$query = $db->getQuery(true)
->select('m.id, m.parent_id, m.title, m.menutype')
->from($db->quoteName('#__menu') . ' AS m')
->where($db->quoteName('m.published') . ' = 1')
->order('m.menutype, m.parent_id, m.ordering');
$db->setQuery($query);
$mitems = $db->loadObjectList();
if (!$mitems)
{
$mitems = array();
}
// Establish the hierarchy of the menu
$children = array();
// First pass - collect children
foreach ($mitems as $v)
{
$pt = $v->parent_id;
$list = @$children[$pt] ? $children[$pt] : array();
array_push($list, $v);
$children[$pt] = $list;
}
// Second pass - get an indent list of the items
$list = static::treerecurse((int) $mitems[0]->parent_id, '', array(), $children, 9999, 0, 0);
// Code that adds menu name to Display of Page(s)
$mitems = array();
if ($all | $unassigned)
{
$mitems[] = JHtml::_('select.option', '<OPTGROUP>', JText::_('JOPTION_MENUS'));
if ($all)
{
$mitems[] = JHtml::_('select.option', 0, JText::_('JALL'));
}
if ($unassigned)
{
$mitems[] = JHtml::_('select.option', -1, JText::_('JOPTION_UNASSIGNED'));
}
$mitems[] = JHtml::_('select.option', '</OPTGROUP>');
}
$lastMenuType = null;
$tmpMenuType = null;
foreach ($list as $list_a)
{
if ($list_a->menutype != $lastMenuType)
{
if ($tmpMenuType)
{
$mitems[] = JHtml::_('select.option', '</OPTGROUP>');
}
$mitems[] = JHtml::_('select.option', '<OPTGROUP>', $list_a->menutype);
$lastMenuType = $list_a->menutype;
$tmpMenuType = $list_a->menutype;
}
$mitems[] = JHtml::_('select.option', $list_a->id, $list_a->title);
}
if ($lastMenuType !== null)
{
$mitems[] = JHtml::_('select.option', '</OPTGROUP>');
}
return $mitems;
}
/**
* Build the list representing the menu tree
*
* @param integer $id Id of the menu item
* @param string $indent The indentation string
* @param array $list The list to process
* @param array &$children The children of the current item
* @param integer $maxlevel The maximum number of levels in the tree
* @param integer $level The starting level
* @param string $type Type of link: component, URL, alias, separator
*
* @return array
*
* @since 1.5
*/
public static function treerecurse($id, $indent, $list, &$children, $maxlevel = 9999, $level = 0, $type = 1)
{
if (@$children[$id] && $level <= $maxlevel)
{
foreach ($children[$id] as $v)
{
$id = $v->id;
if ($type)
{
$pre = '<sup>|_</sup>&#160;';
$spacer = '.&#160;&#160;&#160;&#160;&#160;&#160;';
}
else
{
$pre = '- ';
$spacer = '&#160;&#160;';
}
if ($v->parent_id == 0)
{
$txt = $v->title;
}
else
{
$txt = $pre . $v->title;
}
$list[$id] = $v;
$list[$id]->treename = $indent . $txt;
$list[$id]->children = count(@$children[$id]);
$list = static::treerecurse($id, $indent . $spacer, $list, $children, $maxlevel, $level + 1, $type);
}
}
return $list;
}
}

View File

@ -0,0 +1,62 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage HTML
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
/**
* HTML helper class for rendering numbers.
*
* @package Joomla.Libraries
* @subpackage HTML
* @since 1.6
*/
abstract class JHtmlNumber
{
/**
* Converts bytes to more distinguishable formats such as:
* kilobytes, megabytes, etc.
*
* By default, the proper format will automatically be chosen.
* However, one of the allowed unit types may also be used instead.
*
* @param integer $bytes The number of bytes.
* @param string $unit The type of unit to return.
* @param integer $precision The number of digits to be used after the decimal place.
*
* @return string The number of bytes in the proper units.
*
* @since 1.6
*/
public static function bytes($bytes, $unit = 'auto', $precision = 2)
{
// No explicit casting $bytes to integer here, since it might overflow
// on 32-bit systems
$precision = (int) $precision;
if (empty($bytes))
{
return 0;
}
$unitTypes = array('b', 'kb', 'MB', 'GB', 'TB', 'PB');
// Default automatic method.
$i = floor(log($bytes, 1024));
// User supplied method:
if ($unit !== 'auto' && in_array($unit, $unitTypes))
{
$i = array_search($unit, $unitTypes, true);
}
// TODO Allow conversion of units where $bytes = '32M'.
return round($bytes / pow(1024, $i), $precision) . ' ' . $unitTypes[$i];
}
}

View File

@ -0,0 +1,225 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage HTML
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
/**
* Extended Utility class for all HTML drawing classes.
*
* @package Joomla.Libraries
* @subpackage HTML
* @since 1.6
*/
abstract class JHtmlRules
{
/**
* Creates the HTML for the permissions widget
*
* @param array $actions Array of action objects
* @param integer $assetId Id of a specific asset to create a widget for.
* @param integer $parent Id of the parent of the asset
* @param string $control The form control
* @param string $idPrefix Prefix for the ids assigned to specific action-group pairs
*
* @return string HTML for the permissions widget
*
* @see JAccess
* @see JFormFieldRules
* @since 1.6
*/
public static function assetFormWidget($actions, $assetId = null, $parent = null, $control = 'jform[rules]', $idPrefix = 'jform_rules')
{
$images = static::_getImagesArray();
// Get the user groups.
$groups = static::_getUserGroups();
// Get the incoming inherited rules as well as the asset specific rules.
$inheriting = JAccess::getAssetRules($parent ? $parent : static::_getParentAssetId($assetId), true);
$inherited = JAccess::getAssetRules($assetId, true);
$rules = JAccess::getAssetRules($assetId);
$html = array();
$html[] = '<div class="acl-options">';
$html[] = JHtml::_('tabs.start', 'acl-rules-' . $assetId, array('useCookie' => 1));
$html[] = JHtml::_('tabs.panel', JText::_('JLIB_HTML_ACCESS_SUMMARY'), 'summary');
$html[] = ' <p>' . JText::_('JLIB_HTML_ACCESS_SUMMARY_DESC') . '</p>';
$html[] = ' <table class="aclsummary-table" summary="' . JText::_('JLIB_HTML_ACCESS_SUMMARY_DESC') . '">';
$html[] = ' <caption>' . JText::_('JLIB_HTML_ACCESS_SUMMARY_DESC_CAPTION') . '</caption>';
$html[] = ' <tr>';
$html[] = ' <th class="col1 hidelabeltxt">' . JText::_('JLIB_RULES_GROUPS') . '</th>';
foreach ($actions as $i => $action)
{
$html[] = ' <th class="col' . ($i + 2) . '">' . JText::_($action->title) . '</th>';
}
$html[] = ' </tr>';
foreach ($groups as $i => $group)
{
$html[] = ' <tr class="row' . ($i % 2) . '">';
$html[] = ' <td class="col1">' . $group->text . '</td>';
foreach ($actions as $j => $action)
{
$html[] = ' <td class="col' . ($j + 2) . '">'
. ($assetId ? ($inherited->allow($action->name, $group->identities) ? $images['allow'] : $images['deny'])
: ($inheriting->allow($action->name, $group->identities) ? $images['allow'] : $images['deny'])) . '</td>';
}
$html[] = ' </tr>';
}
$html[] = ' </table>';
foreach ($actions as $action)
{
$actionTitle = JText::_($action->title);
$actionDesc = JText::_($action->description);
$html[] = JHtml::_('tabs.panel', $actionTitle, $action->name);
$html[] = ' <p>' . $actionDesc . '</p>';
$html[] = ' <table class="aclmodify-table" summary="' . strip_tags($actionDesc) . '">';
$html[] = ' <caption>' . JText::_('JLIB_HTML_ACCESS_MODIFY_DESC_CAPTION_ACL') . ' ' . $actionTitle . ' '
. JText::_('JLIB_HTML_ACCESS_MODIFY_DESC_CAPTION_TABLE') . '</caption>';
$html[] = ' <tr>';
$html[] = ' <th class="col1 hidelabeltxt">' . JText::_('JLIB_RULES_GROUP') . '</th>';
$html[] = ' <th class="col2">' . JText::_('JLIB_RULES_INHERIT') . '</th>';
$html[] = ' <th class="col3 hidelabeltxt">' . JText::_('JMODIFY') . '</th>';
$html[] = ' <th class="col4">' . JText::_('JCURRENT') . '</th>';
$html[] = ' </tr>';
foreach ($groups as $i => $group)
{
$selected = $rules->allow($action->name, $group->value);
$html[] = ' <tr class="row' . ($i % 2) . '">';
$html[] = ' <td class="col1">' . $group->text . '</td>';
$html[] = ' <td class="col2">'
. ($inheriting->allow($action->name, $group->identities) ? $images['allow-i'] : $images['deny-i']) . '</td>';
$html[] = ' <td class="col3">';
$html[] = ' <select id="' . $idPrefix . '_' . $action->name . '_' . $group->value
. '" class="inputbox" size="1" name="' . $control . '[' . $action->name . '][' . $group->value . ']" title="'
. JText::sprintf('JLIB_RULES_SELECT_ALLOW_DENY_GROUP', $actionTitle, $group->text) . '">';
$html[] = ' <option value=""' . ($selected === null ? ' selected="selected"' : '') . '>'
. JText::_('JLIB_RULES_INHERIT') . '</option>';
$html[] = ' <option value="1"' . ($selected === true ? ' selected="selected"' : '') . '>'
. JText::_('JLIB_RULES_ALLOWED') . '</option>';
$html[] = ' <option value="0"' . ($selected === false ? ' selected="selected"' : '') . '>'
. JText::_('JLIB_RULES_DENIED') . '</option>';
$html[] = ' </select>';
$html[] = ' </td>';
$html[] = ' <td class="col4">'
. ($assetId ? ($inherited->allow($action->name, $group->identities) ? $images['allow'] : $images['deny'])
: ($inheriting->allow($action->name, $group->identities) ? $images['allow'] : $images['deny'])) . '</td>';
$html[] = ' </tr>';
}
$html[] = ' </table>';
}
$html[] = JHtml::_('tabs.end');
// Build the footer with legend and special purpose buttons.
$html[] = ' <div class="clr"></div>';
$html[] = ' <ul class="acllegend fltlft">';
$html[] = ' <li class="acl-allowed">' . JText::_('JLIB_RULES_ALLOWED') . '</li>';
$html[] = ' <li class="acl-denied">' . JText::_('JLIB_RULES_DENIED') . '</li>';
$html[] = ' </ul>';
$html[] = '</div>';
return implode("\n", $html);
}
/**
* Get the id of the parent asset
*
* @param integer $assetId The asset for which the parentid will be returned
*
* @return integer The id of the parent asset
*
* @since 1.6
*/
protected static function _getParentAssetId($assetId)
{
// Get a database object.
$db = JFactory::getDbo();
$query = $db->getQuery(true);
// Get the user groups from the database.
$query->select($db->quoteName('parent_id'))
->from($db->quoteName('#__assets'))
->where($db->quoteName('id') . ' = ' . (int) $assetId);
$db->setQuery($query);
return (int) $db->loadResult();
}
/**
* Get the user groups
*
* @return array Array of user groups
*
* @since 1.6
*/
protected static function _getUserGroups()
{
// Get a database object.
$db = JFactory::getDbo();
// Get the user groups from the database.
$db->setQuery(
'SELECT a.id AS value, a.title AS text, b.id as parent'
. ' FROM #__usergroups AS a LEFT JOIN #__usergroups AS b ON a.lft >= b.lft AND a.rgt <= b.rgt'
. ' ORDER BY a.lft ASC, b.lft ASC'
);
$result = $db->loadObjectList();
$options = array();
// Pre-compute additional values.
foreach ($result as $option)
{
$end = end($options);
if ($end === false || $end->value != $option->value)
{
$end = $option;
$end->level = 0;
$options[] = $end;
}
else
{
$end->level++;
}
$end->identities[] = $option->parent;
}
return $options;
}
/**
* Get the array of images associate with specific permissions
*
* @return array An associative array of permissions and images
*
* @since 1.6
*/
protected static function _getImagesArray()
{
$images['allow-l'] = '<label class="icon-16-allow" title="' . JText::_('JLIB_RULES_ALLOWED') . '">' . JText::_('JLIB_RULES_ALLOWED')
. '</label>';
$images['deny-l'] = '<label class="icon-16-deny" title="' . JText::_('JLIB_RULES_DENIED') . '">' . JText::_('JLIB_RULES_DENIED') . '</label>';
$images['allow'] = '<a class="icon-16-allow" title="' . JText::_('JLIB_RULES_ALLOWED') . '"> </a>';
$images['deny'] = '<a class="icon-16-deny" title="' . JText::_('JLIB_RULES_DENIED') . '"> </a>';
$images['allow-i'] = '<a class="icon-16-allowinactive" title="' . JText::_('JRULE_ALLOWED_INHERITED') . '"> </a>';
$images['deny-i'] = '<a class="icon-16-denyinactive" title="' . JText::_('JRULE_DENIED_INHERITED') . '"> </a>';
return $images;
}
}

View File

@ -0,0 +1,736 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage HTML
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
/**
* Utility class for creating HTML select lists
*
* @package Joomla.Libraries
* @subpackage HTML
* @since 1.5
*/
abstract class JHtmlSelect
{
/**
* Default values for options. Organized by option group.
*
* @var array
* @since 1.5
*/
static protected $optionDefaults = array(
'option' => array('option.attr' => null, 'option.disable' => 'disable', 'option.id' => null, 'option.key' => 'value',
'option.key.toHtml' => true, 'option.label' => null, 'option.label.toHtml' => true, 'option.text' => 'text',
'option.text.toHtml' => true));
/**
* Generates a yes/no radio list.
*
* @param string $name The value of the HTML name attribute
* @param array $attribs Additional HTML attributes for the <select> tag
* @param string $selected The key that is selected
* @param string $yes Language key for Yes
* @param string $no Language key for no
* @param string $id The id for the field
*
* @return string HTML for the radio list
*
* @since 1.5
* @see JFormFieldRadio
*/
public static function booleanlist($name, $attribs = array(), $selected = null, $yes = 'JYES', $no = 'JNO', $id = false)
{
$arr = array(JHtml::_('select.option', '0', JText::_($no)), JHtml::_('select.option', '1', JText::_($yes)));
return JHtml::_('select.radiolist', $arr, $name, $attribs, 'value', 'text', (int) $selected, $id);
}
/**
* Generates an HTML selection list.
*
* @param array $data An array of objects, arrays, or scalars.
* @param string $name The value of the HTML name attribute.
* @param mixed $attribs Additional HTML attributes for the <select> tag. This
* can be an array of attributes, or an array of options. Treated as options
* if it is the last argument passed. Valid options are:
* Format options, see {@see JHtml::$formatOptions}.
* Selection options, see {@see JHtmlSelect::options()}.
* list.attr, string|array: Additional attributes for the select
* element.
* id, string: Value to use as the select element id attribute.
* Defaults to the same as the name.
* list.select, string|array: Identifies one or more option elements
* to be selected, based on the option key values.
* @param string $optKey The name of the object variable for the option value. If
* set to null, the index of the value array is used.
* @param string $optText The name of the object variable for the option text.
* @param mixed $selected The key that is selected (accepts an array or a string).
* @param mixed $idtag Value of the field id or null by default
* @param boolean $translate True to translate
*
* @return string HTML for the select list.
*
* @since 1.5
*/
public static function genericlist($data, $name, $attribs = null, $optKey = 'value', $optText = 'text', $selected = null, $idtag = false,
$translate = false)
{
// Set default options
$options = array_merge(JHtml::$formatOptions, array('format.depth' => 0, 'id' => false));
if (is_array($attribs) && func_num_args() == 3)
{
// Assume we have an options array
$options = array_merge($options, $attribs);
}
else
{
// Get options from the parameters
$options['id'] = $idtag;
$options['list.attr'] = $attribs;
$options['list.translate'] = $translate;
$options['option.key'] = $optKey;
$options['option.text'] = $optText;
$options['list.select'] = $selected;
}
$attribs = '';
if (isset($options['list.attr']))
{
if (is_array($options['list.attr']))
{
$attribs = JArrayHelper::toString($options['list.attr']);
}
else
{
$attribs = $options['list.attr'];
}
if ($attribs != '')
{
$attribs = ' ' . $attribs;
}
}
$id = $options['id'] !== false ? $options['id'] : $name;
$id = str_replace(array('[', ']'), '', $id);
$baseIndent = str_repeat($options['format.indent'], $options['format.depth']++);
$html = $baseIndent . '<select' . ($id !== '' ? ' id="' . $id . '"' : '') . ' name="' . $name . '"' . $attribs . '>' . $options['format.eol']
. static::options($data, $options) . $baseIndent . '</select>' . $options['format.eol'];
return $html;
}
/**
* Generates a grouped HTML selection list from nested arrays.
*
* @param array $data An array of groups, each of which is an array of options.
* @param string $name The value of the HTML name attribute
* @param array $options Options, an array of key/value pairs. Valid options are:
* Format options, {@see JHtml::$formatOptions}.
* Selection options. See {@see JHtmlSelect::options()}.
* group.id: The property in each group to use as the group id
* attribute. Defaults to none.
* group.label: The property in each group to use as the group
* label. Defaults to "text". If set to null, the data array index key is
* used.
* group.items: The property in each group to use as the array of
* items in the group. Defaults to "items". If set to null, group.id and
* group. label are forced to null and the data element is assumed to be a
* list of selections.
* id: Value to use as the select element id attribute. Defaults to
* the same as the name.
* list.attr: Attributes for the select element. Can be a string or
* an array of key/value pairs. Defaults to none.
* list.select: either the value of one selected option or an array
* of selected options. Default: none.
* list.translate: Boolean. If set, text and labels are translated via
* JText::_().
*
* @return string HTML for the select list
*
* @since 1.5
* @throws RuntimeException If a group has contents that cannot be processed.
*/
public static function groupedlist($data, $name, $options = array())
{
// Set default options and overwrite with anything passed in
$options = array_merge(
JHtml::$formatOptions,
array('format.depth' => 0, 'group.items' => 'items', 'group.label' => 'text', 'group.label.toHtml' => true, 'id' => false),
$options
);
// Apply option rules
if ($options['group.items'] === null)
{
$options['group.label'] = null;
}
$attribs = '';
if (isset($options['list.attr']))
{
if (is_array($options['list.attr']))
{
$attribs = JArrayHelper::toString($options['list.attr']);
}
else
{
$attribs = $options['list.attr'];
}
if ($attribs != '')
{
$attribs = ' ' . $attribs;
}
}
$id = $options['id'] !== false ? $options['id'] : $name;
$id = str_replace(array('[', ']'), '', $id);
// Disable groups in the options.
$options['groups'] = false;
$baseIndent = str_repeat($options['format.indent'], $options['format.depth']++);
$html = $baseIndent . '<select' . ($id !== '' ? ' id="' . $id . '"' : '') . ' name="' . $name . '"' . $attribs . '>' . $options['format.eol'];
$groupIndent = str_repeat($options['format.indent'], $options['format.depth']++);
foreach ($data as $dataKey => $group)
{
$label = $dataKey;
$id = '';
$noGroup = is_int($dataKey);
if ($options['group.items'] == null)
{
// Sub-list is an associative array
$subList = $group;
}
elseif (is_array($group))
{
// Sub-list is in an element of an array.
$subList = $group[$options['group.items']];
if (isset($group[$options['group.label']]))
{
$label = $group[$options['group.label']];
$noGroup = false;
}
if (isset($options['group.id']) && isset($group[$options['group.id']]))
{
$id = $group[$options['group.id']];
$noGroup = false;
}
}
elseif (is_object($group))
{
// Sub-list is in a property of an object
$subList = $group->$options['group.items'];
if (isset($group->$options['group.label']))
{
$label = $group->$options['group.label'];
$noGroup = false;
}
if (isset($options['group.id']) && isset($group->$options['group.id']))
{
$id = $group->$options['group.id'];
$noGroup = false;
}
}
else
{
throw new RuntimeException('Invalid group contents.', 1);
}
if ($noGroup)
{
$html .= static::options($subList, $options);
}
else
{
$html .= $groupIndent . '<optgroup' . (empty($id) ? '' : ' id="' . $id . '"') . ' label="'
. ($options['group.label.toHtml'] ? htmlspecialchars($label, ENT_COMPAT, 'UTF-8') : $label) . '">' . $options['format.eol']
. static::options($subList, $options) . $groupIndent . '</optgroup>' . $options['format.eol'];
}
}
$html .= $baseIndent . '</select>' . $options['format.eol'];
return $html;
}
/**
* Generates a selection list of integers.
*
* @param integer $start The start integer
* @param integer $end The end integer
* @param integer $inc The increment
* @param string $name The value of the HTML name attribute
* @param mixed $attribs Additional HTML attributes for the <select> tag, an array of
* attributes, or an array of options. Treated as options if it is the last
* argument passed.
* @param mixed $selected The key that is selected
* @param string $format The printf format to be applied to the number
*
* @return string HTML for the select list
*
* @since 1.5
*/
public static function integerlist($start, $end, $inc, $name, $attribs = null, $selected = null, $format = '')
{
// Set default options
$options = array_merge(JHtml::$formatOptions, array('format.depth' => 0, 'option.format' => '', 'id' => null));
if (is_array($attribs) && func_num_args() == 5)
{
// Assume we have an options array
$options = array_merge($options, $attribs);
// Extract the format and remove it from downstream options
$format = $options['option.format'];
unset($options['option.format']);
}
else
{
// Get options from the parameters
$options['list.attr'] = $attribs;
$options['list.select'] = $selected;
}
$start = (int) $start;
$end = (int) $end;
$inc = (int) $inc;
$data = array();
for ($i = $start; $i <= $end; $i += $inc)
{
$data[$i] = $format ? sprintf($format, $i) : $i;
}
// Tell genericlist() to use array keys
$options['option.key'] = null;
return JHtml::_('select.genericlist', $data, $name, $options);
}
/**
* Create a placeholder for an option group.
*
* @param string $text The text for the option
* @param string $optKey The returned object property name for the value
* @param string $optText The returned object property name for the text
*
* @return object
*
* @deprecated 4.0 Use JHtmlSelect::groupedList()
* @see JHtmlSelect::groupedList()
* @since 1.5
*/
public static function optgroup($text, $optKey = 'value', $optText = 'text')
{
JLog::add('JHtmlSelect::optgroup() is deprecated, use JHtmlSelect::groupedList() instead.', JLog::WARNING, 'deprecated');
// Set initial state
static $state = 'open';
// Toggle between open and close states:
switch ($state)
{
case 'open':
$obj = new stdClass;
$obj->$optKey = '<OPTGROUP>';
$obj->$optText = $text;
$state = 'close';
break;
case 'close':
$obj = new stdClass;
$obj->$optKey = '</OPTGROUP>';
$obj->$optText = $text;
$state = 'open';
break;
}
return $obj;
}
/**
* Create an object that represents an option in an option list.
*
* @param string $value The value of the option
* @param string $text The text for the option
* @param mixed $optKey If a string, the returned object property name for
* the value. If an array, options. Valid options are:
* attr: String|array. Additional attributes for this option.
* Defaults to none.
* disable: Boolean. If set, this option is disabled.
* label: String. The value for the option label.
* option.attr: The property in each option array to use for
* additional selection attributes. Defaults to none.
* option.disable: The property that will hold the disabled state.
* Defaults to "disable".
* option.key: The property that will hold the selection value.
* Defaults to "value".
* option.label: The property in each option array to use as the
* selection label attribute. If a "label" option is provided, defaults to
* "label", if no label is given, defaults to null (none).
* option.text: The property that will hold the the displayed text.
* Defaults to "text". If set to null, the option array is assumed to be a
* list of displayable scalars.
* @param string $optText The property that will hold the the displayed text. This
* parameter is ignored if an options array is passed.
* @param boolean $disable Not used.
*
* @return object
*
* @since 1.5
*/
public static function option($value, $text = '', $optKey = 'value', $optText = 'text', $disable = false)
{
$options = array('attr' => null, 'disable' => false, 'option.attr' => null, 'option.disable' => 'disable', 'option.key' => 'value',
'option.label' => null, 'option.text' => 'text');
if (is_array($optKey))
{
// Merge in caller's options
$options = array_merge($options, $optKey);
}
else
{
// Get options from the parameters
$options['option.key'] = $optKey;
$options['option.text'] = $optText;
$options['disable'] = $disable;
}
$obj = new stdClass;
$obj->$options['option.key'] = $value;
$obj->$options['option.text'] = trim($text) ? $text : $value;
/*
* If a label is provided, save it. If no label is provided and there is
* a label name, initialise to an empty string.
*/
$hasProperty = $options['option.label'] !== null;
if (isset($options['label']))
{
$labelProperty = $hasProperty ? $options['option.label'] : 'label';
$obj->$labelProperty = $options['label'];
}
elseif ($hasProperty)
{
$obj->$options['option.label'] = '';
}
// Set attributes only if there is a property and a value
if ($options['attr'] !== null)
{
$obj->$options['option.attr'] = $options['attr'];
}
// Set disable only if it has a property and a value
if ($options['disable'] !== null)
{
$obj->$options['option.disable'] = $options['disable'];
}
return $obj;
}
/**
* Generates the option tags for an HTML select list (with no select tag
* surrounding the options).
*
* @param array $arr An array of objects, arrays, or values.
* @param mixed $optKey If a string, this is the name of the object variable for
* the option value. If null, the index of the array of objects is used. If
* an array, this is a set of options, as key/value pairs. Valid options are:
* -Format options, {@see JHtml::$formatOptions}.
* -groups: Boolean. If set, looks for keys with the value
* "&lt;optgroup>" and synthesizes groups from them. Deprecated. Defaults
* true for backwards compatibility.
* -list.select: either the value of one selected option or an array
* of selected options. Default: none.
* -list.translate: Boolean. If set, text and labels are translated via
* JText::_(). Default is false.
* -option.id: The property in each option array to use as the
* selection id attribute. Defaults to none.
* -option.key: The property in each option array to use as the
* selection value. Defaults to "value". If set to null, the index of the
* option array is used.
* -option.label: The property in each option array to use as the
* selection label attribute. Defaults to null (none).
* -option.text: The property in each option array to use as the
* displayed text. Defaults to "text". If set to null, the option array is
* assumed to be a list of displayable scalars.
* -option.attr: The property in each option array to use for
* additional selection attributes. Defaults to none.
* -option.disable: The property that will hold the disabled state.
* Defaults to "disable".
* -option.key: The property that will hold the selection value.
* Defaults to "value".
* -option.text: The property that will hold the the displayed text.
* Defaults to "text". If set to null, the option array is assumed to be a
* list of displayable scalars.
* @param string $optText The name of the object variable for the option text.
* @param mixed $selected The key that is selected (accepts an array or a string)
* @param boolean $translate Translate the option values.
*
* @return string HTML for the select list
*
* @since 1.5
*/
public static function options($arr, $optKey = 'value', $optText = 'text', $selected = null, $translate = false)
{
$options = array_merge(
JHtml::$formatOptions,
static::$optionDefaults['option'],
array('format.depth' => 0, 'groups' => true, 'list.select' => null, 'list.translate' => false)
);
if (is_array($optKey))
{
// Set default options and overwrite with anything passed in
$options = array_merge($options, $optKey);
}
else
{
// Get options from the parameters
$options['option.key'] = $optKey;
$options['option.text'] = $optText;
$options['list.select'] = $selected;
$options['list.translate'] = $translate;
}
$html = '';
$baseIndent = str_repeat($options['format.indent'], $options['format.depth']);
foreach ($arr as $elementKey => &$element)
{
$attr = '';
$extra = '';
$label = '';
$id = '';
if (is_array($element))
{
$key = $options['option.key'] === null ? $elementKey : $element[$options['option.key']];
$text = $element[$options['option.text']];
if (isset($element[$options['option.attr']]))
{
$attr = $element[$options['option.attr']];
}
if (isset($element[$options['option.id']]))
{
$id = $element[$options['option.id']];
}
if (isset($element[$options['option.label']]))
{
$label = $element[$options['option.label']];
}
if (isset($element[$options['option.disable']]) && $element[$options['option.disable']])
{
$extra .= ' disabled="disabled"';
}
}
elseif (is_object($element))
{
$key = $options['option.key'] === null ? $elementKey : $element->$options['option.key'];
$text = $element->$options['option.text'];
if (isset($element->$options['option.attr']))
{
$attr = $element->$options['option.attr'];
}
if (isset($element->$options['option.id']))
{
$id = $element->$options['option.id'];
}
if (isset($element->$options['option.label']))
{
$label = $element->$options['option.label'];
}
if (isset($element->$options['option.disable']) && $element->$options['option.disable'])
{
$extra .= ' disabled="disabled"';
}
}
else
{
// This is a simple associative array
$key = $elementKey;
$text = $element;
}
/*
* The use of options that contain optgroup HTML elements was
* somewhat hacked for J1.5. J1.6 introduces the grouplist() method
* to handle this better. The old solution is retained through the
* "groups" option, which defaults true in J1.6, but should be
* deprecated at some point in the future.
*/
$key = (string) $key;
if ($options['groups'] && $key == '<OPTGROUP>')
{
$html .= $baseIndent . '<optgroup label="' . ($options['list.translate'] ? JText::_($text) : $text) . '">' . $options['format.eol'];
$baseIndent = str_repeat($options['format.indent'], ++$options['format.depth']);
}
elseif ($options['groups'] && $key == '</OPTGROUP>')
{
$baseIndent = str_repeat($options['format.indent'], --$options['format.depth']);
$html .= $baseIndent . '</optgroup>' . $options['format.eol'];
}
else
{
// If no string after hyphen - take hyphen out
$splitText = explode(' - ', $text, 2);
$text = $splitText[0];
if (isset($splitText[1]))
{
$text .= ' - ' . $splitText[1];
}
if ($options['list.translate'] && !empty($label))
{
$label = JText::_($label);
}
if ($options['option.label.toHtml'])
{
$label = htmlentities($label);
}
if (is_array($attr))
{
$attr = JArrayHelper::toString($attr);
}
else
{
$attr = trim($attr);
}
$extra = ($id ? ' id="' . $id . '"' : '') . ($label ? ' label="' . $label . '"' : '') . ($attr ? ' ' . $attr : '') . $extra;
if (is_array($options['list.select']))
{
foreach ($options['list.select'] as $val)
{
$key2 = is_object($val) ? $val->$options['option.key'] : $val;
if ($key == $key2)
{
$extra .= ' selected="selected"';
break;
}
}
}
elseif ((string) $key == (string) $options['list.select'])
{
$extra .= ' selected="selected"';
}
if ($options['list.translate'])
{
$text = JText::_($text);
}
// Generate the option, encoding as required
$html .= $baseIndent . '<option value="' . ($options['option.key.toHtml'] ? htmlspecialchars($key, ENT_COMPAT, 'UTF-8') : $key) . '"'
. $extra . '>';
$html .= $options['option.text.toHtml'] ? htmlentities(html_entity_decode($text, ENT_COMPAT, 'UTF-8'), ENT_COMPAT, 'UTF-8') : $text;
$html .= '</option>' . $options['format.eol'];
}
}
return $html;
}
/**
* Generates an HTML radio list.
*
* @param array $data An array of objects
* @param string $name The value of the HTML name attribute
* @param string $attribs Additional HTML attributes for the <select> tag
* @param mixed $optKey The key that is selected
* @param string $optText The name of the object variable for the option value
* @param string $selected The name of the object variable for the option text
* @param boolean $idtag Value of the field id or null by default
* @param boolean $translate True if options will be translated
*
* @return string HTML for the select list
*
* @since 1.5
*/
public static function radiolist($data, $name, $attribs = null, $optKey = 'value', $optText = 'text', $selected = null, $idtag = false,
$translate = false)
{
reset($data);
if (is_array($attribs))
{
$attribs = JArrayHelper::toString($attribs);
}
$id_text = $idtag ? $idtag : $name;
$html = '<div class="controls">';
foreach ($data as $obj)
{
$k = $obj->$optKey;
$t = $translate ? JText::_($obj->$optText) : $obj->$optText;
$id = (isset($obj->id) ? $obj->id : null);
$extra = '';
$extra .= $id ? ' id="' . $obj->id . '"' : '';
if (is_array($selected))
{
foreach ($selected as $val)
{
$k2 = is_object($val) ? $val->$optKey : $val;
if ($k == $k2)
{
$extra .= ' selected="selected"';
break;
}
}
}
else
{
$extra .= ((string) $k == (string) $selected ? ' checked="checked"' : '');
}
$html .= "\n\t" . '<label for="' . $id_text . $k . '" id="' . $id_text . $k . '-lbl" class="radio">';
$html .= "\n\t\n\t" . '<input type="radio" name="' . $name . '" id="' . $id_text . $k . '" value="' . $k . '" ' . $extra . ' '
. $attribs . '>' . $t;
$html .= "\n\t" . '</label>';
}
$html .= '</div>';
$html .= "\n";
return $html;
}
}

View File

@ -0,0 +1,152 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage HTML
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_BASE') or die;
/**
* Utility class to render a list view sidebar
*
* @package Joomla.Libraries
* @subpackage HTML
* @since 3.0
*/
abstract class JHtmlSidebar
{
/**
* Menu entries
*
* @var array
* @since 3.0
*/
protected static $entries = array();
/**
* Filters
*
* @var array
* @since 3.0
*/
protected static $filters = array();
/**
* Value for the action attribute of the form.
*
* @var string
* @since 3.0
*/
protected static $action = '';
/**
* Render the sidebar.
*
* @return string The necessary HTML to display the sidebar
*
* @since 3.0
*/
public static function render()
{
// Collect display data
$data = new stdClass;
$data->list = static::getEntries();
$data->filters = static::getFilters();
$data->action = static::getAction();
$data->displayMenu = count($data->list);
$data->displayFilters = count($data->filters);
$data->hide = JFactory::getApplication()->input->getBool('hidemainmenu');
// Create a layout object and ask it to render the sidebar
$layout = new JLayoutFile('joomla.sidebars.submenu');
$sidebarHtml = $layout->render($data);
return $sidebarHtml;
}
/**
* Method to add a menu item to submenu.
*
* @param string $name Name of the menu item.
* @param string $link URL of the menu item.
* @param bool $active True if the item is active, false otherwise.
*
* @return void
*
* @since 3.0
*/
public static function addEntry($name, $link = '', $active = false)
{
array_push(static::$entries, array($name, $link, $active));
}
/**
* Returns an array of all submenu entries
*
* @return array
*
* @since 3.0
*/
public static function getEntries()
{
return static::$entries;
}
/**
* Method to add a filter to the submenu
*
* @param string $label Label for the menu item.
* @param string $name Name for the filter. Also used as id.
* @param string $options Options for the select field.
* @param bool $noDefault Don't the label as the empty option
*
* @return void
*
* @since 3.0
*/
public static function addFilter($label, $name, $options, $noDefault = false)
{
array_push(static::$filters, array('label' => $label, 'name' => $name, 'options' => $options, 'noDefault' => $noDefault));
}
/**
* Returns an array of all filters
*
* @return array
*
* @since 3.0
*/
public static function getFilters()
{
return static::$filters;
}
/**
* Set value for the action attribute of the filter form
*
* @param string $action Value for the action attribute of the form
*
* @return void
*
* @since 3.0
*/
public static function setAction($action)
{
static::$action = $action;
}
/**
* Get value for the action attribute of the filter form
*
* @return string
*
* @since 3.0
*/
public static function getAction()
{
return static::$action;
}
}

View File

@ -0,0 +1,120 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage HTML
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
/**
* Utility class for Sliders elements
*
* @package Joomla.Libraries
* @subpackage HTML
* @since 1.6
*/
abstract class JHtmlSliders
{
/**
* Creates a panes and loads the javascript behavior for it.
*
* @param string $group The pane identifier.
* @param array $params An array of options.
*
* @return string
*
* @since 1.6
*/
public static function start($group = 'sliders', $params = array())
{
static::loadBehavior($group, $params);
return '<div id="' . $group . '" class="pane-sliders"><div style="display:none;"><div>';
}
/**
* Close the current pane.
*
* @return string hTML to close the pane
*
* @since 1.6
*/
public static function end()
{
return '</div></div></div>';
}
/**
* Begins the display of a new panel.
*
* @param string $text Text to display.
* @param string $id Identifier of the panel.
*
* @return string HTML to start a panel
*
* @since 1.6
*/
public static function panel($text, $id)
{
return '</div></div><div class="panel"><h3 class="pane-toggler title" id="' . $id . '"><a href="javascript:void(0);"><span>' . $text
. '</span></a></h3><div class="pane-slider content">';
}
/**
* Load the JavaScript behavior.
*
* @param string $group The pane identifier.
* @param array $params Array of options.
*
* @return void
*
* @since 1.6
*/
protected static function loadBehavior($group, $params = array())
{
static $loaded = array();
if (!array_key_exists($group, $loaded))
{
// Get the JInput object
$input = JFactory::getApplication()->input;
$loaded[$group] = true;
// Include mootools framework.
JHtml::_('behavior.framework', true);
$document = JFactory::getDocument();
$display = (isset($params['startOffset']) && isset($params['startTransition']) && $params['startTransition'])
? (int) $params['startOffset'] : null;
$show = (isset($params['startOffset']) && !(isset($params['startTransition']) && $params['startTransition']))
? (int) $params['startOffset'] : null;
$opt['onActive'] = "\\function(toggler, i) {toggler.addClass('pane-toggler-down');" .
"toggler.removeClass('pane-toggler');i.addClass('pane-down');i.removeClass('pane-hide');Cookie.write('jpanesliders_"
. $group . "',$$('div#" . $group . ".pane-sliders > .panel > h3').indexOf(toggler));}";
$opt['onBackground'] = "\\function(toggler, i) {toggler.addClass('pane-toggler');" .
"toggler.removeClass('pane-toggler-down');i.addClass('pane-hide');i.removeClass('pane-down');if($$('div#"
. $group . ".pane-sliders > .panel > h3').length==$$('div#" . $group
. ".pane-sliders > .panel > h3.pane-toggler').length) Cookie.write('jpanesliders_" . $group . "',-1);}";
$opt['duration'] = (isset($params['duration'])) ? (int) $params['duration'] : 300;
$opt['display'] = (isset($params['useCookie']) && $params['useCookie']) ? $input->cookie->get('jpanesliders_' . $group, $display, 'integer')
: $display;
$opt['show'] = (isset($params['useCookie']) && $params['useCookie']) ? $input->cookie->get('jpanesliders_' . $group, $show, 'integer') : $show;
$opt['opacity'] = (isset($params['opacityTransition']) && ($params['opacityTransition'])) ? 'true' : 'false';
$opt['alwaysHide'] = (isset($params['allowAllClose']) && (!$params['allowAllClose'])) ? 'false' : 'true';
$options = JHtml::getJSObject($opt);
$js = "window.addEvent('domready', function(){ new Fx.Accordion($$('div#" . $group
. ".pane-sliders > .panel > h3.pane-toggler'), $$('div#" . $group . ".pane-sliders > .panel > div.pane-slider'), " . $options
. "); });";
$document->addScriptDeclaration($js);
}
}
}

View File

@ -0,0 +1,107 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage HTML
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
/**
* HTML utility class for creating a sortable table list
*
* @package Joomla.Libraries
* @subpackage HTML
* @since 3.0
*/
abstract class JHtmlSortablelist
{
/**
* @var array Array containing information for loaded files
* @since 3.0
*/
protected static $loaded = array();
/**
* Method to load the Sortable script and make table sortable
*
* @param string $tableId DOM id of the table
* @param string $formId DOM id of the form
* @param string $sortDir Sort direction
* @param string $saveOrderingUrl Save ordering url, ajax-load after an item dropped
* @param boolean $proceedSaveOrderButton Set whether a save order button is displayed
* @param boolean $nestedList Set whether the list is a nested list
*
* @return void
*
* @since 3.0
*/
public static function sortable($tableId, $formId, $sortDir = 'asc', $saveOrderingUrl, $proceedSaveOrderButton = true, $nestedList = false)
{
// Only load once
if (isset(static::$loaded[__METHOD__]))
{
return;
}
// Depends on jQuery UI
JHtml::_('jquery.ui', array('core', 'sortable'));
JHtml::_('script', 'jui/sortablelist.js', false, true);
JHtml::_('stylesheet', 'jui/sortablelist.css', false, true, false);
// Attach sortable to document
JFactory::getDocument()->addScriptDeclaration("
(function ($){
$(document).ready(function (){
var sortableList = new $.JSortableList('#" . $tableId . " tbody','" . $formId . "','" . $sortDir . "' , '" . $saveOrderingUrl . "','','" . $nestedList . "');
});
})(jQuery);
"
);
if ($proceedSaveOrderButton)
{
static::_proceedSaveOrderButton();
}
// Set static array
static::$loaded[__METHOD__] = true;
return;
}
/**
* Method to inject script for enabled and disable Save order button
* when changing value of ordering input boxes
*
* @return void
*
* @since 3.0
*/
public static function _proceedSaveOrderButton()
{
JFactory::getDocument()->addScriptDeclaration(
"(function ($){
$(document).ready(function (){
var saveOrderButton = $('.saveorder');
saveOrderButton.css({'opacity':'0.2', 'cursor':'default'}).attr('onclick','return false;');
var oldOrderingValue = '';
$('.text-area-order').focus(function ()
{
oldOrderingValue = $(this).attr('value');
})
.keyup(function (){
var newOrderingValue = $(this).attr('value');
if (oldOrderingValue != newOrderingValue)
{
saveOrderButton.css({'opacity':'1', 'cursor':'pointer'}).removeAttr('onclick')
}
});
});
})(jQuery);"
);
return;
}
}

View File

@ -0,0 +1,296 @@
<?php
/**
* @package Joomla.Platform
* @subpackage HTML
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
/**
* HTML helper class for rendering manipulated strings.
*
* @package Joomla.Platform
* @subpackage HTML
* @since 1.6
*/
abstract class JHtmlString
{
/**
* Truncates text blocks over the specified character limit and closes
* all open HTML tags. The method will optionally not truncate an individual
* word, it will find the first space that is within the limit and
* truncate at that point. This method is UTF-8 safe.
*
* @param string $text The text to truncate.
* @param integer $length The maximum length of the text.
* @param boolean $noSplit Don't split a word if that is where the cutoff occurs (default: true).
* @param boolean $allowHtml Allow HTML tags in the output, and close any open tags (default: true).
*
* @return string The truncated text.
*
* @since 1.6
*/
public static function truncate($text, $length = 0, $noSplit = true, $allowHtml = true)
{
// Assume a lone open tag is invalid HTML.
if ($length == 1 && substr($text, 0, 1) == '<')
{
return '...';
}
// Check if HTML tags are allowed.
if (!$allowHtml)
{
// Deal with spacing issues in the input.
$text = str_replace('>', '> ', $text);
$text = str_replace(array('&nbsp;', '&#160;'), ' ', $text);
$text = JString::trim(preg_replace('#\s+#mui', ' ', $text));
// Strip the tags from the input and decode entities.
$text = strip_tags($text);
$text = html_entity_decode($text, ENT_QUOTES, 'UTF-8');
// Remove remaining extra spaces.
$text = str_replace('&nbsp;', ' ', $text);
$text = JString::trim(preg_replace('#\s+#mui', ' ', $text));
}
// Whether or not allowing HTML, truncate the item text if it is too long.
if ($length > 0 && JString::strlen($text) > $length)
{
$tmp = trim(JString::substr($text, 0, $length));
if (substr($tmp, 0, 1) == '<' && strpos($tmp, '>') === false)
{
return '...';
}
// $noSplit true means that we do not allow splitting of words.
if ($noSplit)
{
// Find the position of the last space within the allowed length.
$offset = JString::strrpos($tmp, ' ');
$tmp = JString::substr($tmp, 0, $offset + 1);
// If there are no spaces and the string is longer than the maximum
// we need to just use the ellipsis. In that case we are done.
if ($offset === false && strlen($text) > $length)
{
return '...';
}
if (JString::strlen($tmp) > $length - 3)
{
$tmp = trim(JString::substr($tmp, 0, JString::strrpos($tmp, ' ')));
}
}
if ($allowHtml)
{
// Put all opened tags into an array
preg_match_all("#<([a-z][a-z0-9]*)\b.*?(?!/)>#i", $tmp, $result);
$openedTags = $result[1];
// Some tags self close so they do not need a separate close tag.
$openedTags = array_diff($openedTags, array("img", "hr", "br"));
$openedTags = array_values($openedTags);
// Put all closed tags into an array
preg_match_all("#</([a-z]+)>#iU", $tmp, $result);
$closedTags = $result[1];
$numOpened = count($openedTags);
// All tags are closed so trim the text and finish.
if (count($closedTags) == $numOpened)
{
return trim($tmp) . '...';
}
// Closing tags need to be in the reverse order of opening tags.
$openedTags = array_reverse($openedTags);
// Close tags
for ($i = 0; $i < $numOpened; $i++)
{
if (!in_array($openedTags[$i], $closedTags))
{
$tmp .= "</" . $openedTags[$i] . ">";
}
else
{
unset($closedTags[array_search($openedTags[$i], $closedTags)]);
}
}
}
if ($tmp === false || strlen($text) > strlen($tmp))
{
$text = trim($tmp) . '...';
}
}
// Clean up any internal spaces created by the processing.
$text = str_replace(' </', '</', $text);
$text = str_replace(' ...', '...', $text);
return $text;
}
/**
* Method to extend the truncate method to more complex situations
*
* The goal is to get the proper length plain text string with as much of
* the html intact as possible with all tags properly closed.
*
* @param string $html The content of the introtext to be truncated
* @param integer $maxLength The maximum number of characters to render
* @param boolean $noSplit Don't split a word if that is where the cutoff occurs (default: true).
*
* @return string The truncated string. If the string is truncated an ellipsis
* (...) will be appended.
*
* @note If a maximum length of 3 or less is selected and the text has more than
* that number of characters an ellipsis will be displayed.
* This method will not create valid HTML from malformed HTML.
*
* @since 3.1
*/
public static function truncateComplex($html, $maxLength = 0, $noSplit = true)
{
// Start with some basic rules.
$baseLength = strlen($html);
// If the original HTML string is shorter than the $maxLength do nothing and return that.
if ($baseLength <= $maxLength || $maxLength == 0)
{
return $html;
}
// Take care of short simple cases.
if ($maxLength <= 3 && substr($html, 0, 1) != '<' && strpos(substr($html, 0, $maxLength - 1), '<') === false && $baseLength > $maxLength)
{
return '...';
}
// Deal with maximum length of 1 where the string starts with a tag.
if ($maxLength == 1 && substr($html, 0, 1) == '<')
{
$endTagPos = strlen(strstr($html, '>', true));
$tag = substr($html, 1, $endTagPos);
$l = $endTagPos + 1;
if ($noSplit)
{
return substr($html, 0, $l) . '</' . $tag . '...';
}
// TODO: $character doesn't seem to be used...
$character = substr(strip_tags($html), 0, 1);
return substr($html, 0, $l) . '</' . $tag . '...';
}
// First get the truncated plain text string. This is the rendered text we want to end up with.
$ptString = JHtml::_('string.truncate', $html, $maxLength, $noSplit, $allowHtml = false);
// It's all HTML, just return it.
if (strlen($ptString) == 0)
{
return $html;
}
// If the plain text is shorter than the max length the variable will not end in ...
// In that case we use the whole string.
if (substr($ptString, -3) != '...')
{
return $html;
}
// Regular truncate gives us the ellipsis but we want to go back for text and tags.
if ($ptString == '...')
{
$stripped = substr(strip_tags($html), 0, $maxLength);
$ptString = JHtml::_('string.truncate', $stripped, $maxLength, $noSplit, $allowHtml = false);
}
// We need to trim the ellipsis that truncate adds.
$ptString = rtrim($ptString, '.');
// Now deal with more complex truncation.
while ($maxLength <= $baseLength)
{
// Get the truncated string assuming HTML is allowed.
$htmlString = JHtml::_('string.truncate', $html, $maxLength, $noSplit, $allowHtml = true);
if ($htmlString == '...' && strlen($ptString) + 3 > $maxLength)
{
return $htmlString;
}
$htmlString = rtrim($htmlString, '.');
// Now get the plain text from the HTML string and trim it.
$htmlStringToPtString = JHtml::_('string.truncate', $htmlString, $maxLength, $noSplit, $allowHtml = false);
$htmlStringToPtString = rtrim($htmlStringToPtString, '.');
// If the new plain text string matches the original plain text string we are done.
if ($ptString == $htmlStringToPtString)
{
return $htmlString . '...';
}
// Get the number of HTML tag characters in the first $maxLength characters
$diffLength = strlen($ptString) - strlen($htmlStringToPtString);
if ($diffLength <= 0)
{
return $htmlString . '...';
}
// Set new $maxlength that adjusts for the HTML tags
$maxLength += $diffLength;
}
}
/**
* Abridges text strings over the specified character limit. The
* behavior will insert an ellipsis into the text replacing a section
* of variable size to ensure the string does not exceed the defined
* maximum length. This method is UTF-8 safe.
*
* For example, it transforms "Really long title" to "Really...title".
*
* Note that this method does not scan for HTML tags so will potentially break them.
*
* @param string $text The text to abridge.
* @param integer $length The maximum length of the text (default is 50).
* @param integer $intro The maximum length of the intro text (default is 30).
*
* @return string The abridged text.
*
* @since 1.6
*/
public static function abridge($text, $length = 50, $intro = 30)
{
// Abridge the item text if it is too long.
if (JString::strlen($text) > $length)
{
// Determine the remaining text length.
$remainder = $length - ($intro + 3);
// Extract the beginning and ending text sections.
$beg = JString::substr($text, 0, $intro);
$end = JString::substr($text, JString::strlen($text) - $remainder);
// Build the resulting string.
$text = $beg . '...' . $end;
}
return $text;
}
}

106
libraries/cms/html/tabs.php Normal file
View File

@ -0,0 +1,106 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage HTML
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
/**
* Utility class for Tabs elements.
*
* @package Joomla.Libraries
* @subpackage HTML
* @since 1.6
*/
abstract class JHtmlTabs
{
/**
* Creates a panes and creates the JavaScript object for it.
*
* @param string $group The pane identifier.
* @param array $params An array of option.
*
* @return string
*
* @since 1.6
*/
public static function start($group = 'tabs', $params = array())
{
static::loadBehavior($group, $params);
return '<dl class="tabs" id="' . $group . '"><dt style="display:none;"></dt><dd style="display:none;">';
}
/**
* Close the current pane
*
* @return string HTML to close the pane
*
* @since 1.6
*/
public static function end()
{
return '</dd></dl>';
}
/**
* Begins the display of a new panel.
*
* @param string $text Text to display.
* @param string $id Identifier of the panel.
*
* @return string HTML to start a new panel
*
* @since 1.6
*/
public static function panel($text, $id)
{
return '</dd><dt class="tabs ' . $id . '"><span><h3><a href="javascript:void(0);">' . $text . '</a></h3></span></dt><dd class="tabs">';
}
/**
* Load the JavaScript behavior.
*
* @param string $group The pane identifier.
* @param array $params Array of options.
*
* @return void
*
* @since 1.6
*/
protected static function loadBehavior($group, $params = array())
{
static $loaded = array();
if (!array_key_exists((string) $group, $loaded))
{
// Include MooTools framework
JHtml::_('behavior.framework', true);
$opt['onActive'] = (isset($params['onActive'])) ? '\\' . $params['onActive'] : null;
$opt['onBackground'] = (isset($params['onBackground'])) ? '\\' . $params['onBackground'] : null;
$opt['display'] = (isset($params['startOffset'])) ? (int) $params['startOffset'] : null;
$opt['useStorage'] = (isset($params['useCookie']) && $params['useCookie']) ? 'true' : 'false';
$opt['titleSelector'] = "dt.tabs";
$opt['descriptionSelector'] = "dd.tabs";
$options = JHtml::getJSObject($opt);
$js = ' window.addEvent(\'domready\', function(){
$$(\'dl#' . $group . '.tabs\').each(function(tabs){
new JTabs(tabs, ' . $options . ');
});
});';
$document = JFactory::getDocument();
$document->addScriptDeclaration($js);
JHtml::_('script', 'system/tabs.js', false, true);
$loaded[(string) $group] = true;
}
}
}

239
libraries/cms/html/tag.php Normal file
View File

@ -0,0 +1,239 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage HTML
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_BASE') or die;
/**
* Utility class for tags
*
* @package Joomla.Libraries
* @subpackage HTML
* @since 3.1
*/
abstract class JHtmlTag
{
/**
* Cached array of the tag items.
*
* @var array
* @since 3.1
*/
protected static $items = array();
/**
* Returns an array of tags.
*
* @param array $config An array of configuration options. By default, only
* published and unpublished categories are returned.
*
* @return array
*
* @since 3.1
*/
public static function options($config = array('filter.published' => array(0, 1)))
{
$hash = md5(serialize($config));
if (!isset(static::$items[$hash]))
{
$config = (array) $config;
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select('a.id, a.title, a.level')
->from('#__tags AS a')
->where('a.parent_id > 0');
// Filter on the published state
if (isset($config['filter.published']))
{
if (is_numeric($config['filter.published']))
{
$query->where('a.published = ' . (int) $config['filter.published']);
}
elseif (is_array($config['filter.published']))
{
JArrayHelper::toInteger($config['filter.published']);
$query->where('a.published IN (' . implode(',', $config['filter.published']) . ')');
}
}
// Filter on the language
if (isset($config['filter.language']))
{
if (is_string($config['filter.language']))
{
$query->where('a.language = ' . $db->quote($config['filter.language']));
}
elseif (is_array($config['filter.language']))
{
foreach ($config['filter.language'] as &$language)
{
$language = $db->quote($language);
}
$query->where('a.language IN (' . implode(',', $config['filter.language']) . ')');
}
}
$query->order('a.lft');
$db->setQuery($query);
$items = $db->loadObjectList();
// Assemble the list options.
static::$items[$hash] = array();
foreach ($items as &$item)
{
$repeat = ($item->level - 1 >= 0) ? $item->level - 1 : 0;
$item->title = str_repeat('- ', $repeat) . $item->title;
static::$items[$hash][] = JHtml::_('select.option', $item->id, $item->title);
}
}
return static::$items[$hash];
}
/**
* Returns an array of tags.
*
* @param array $config An array of configuration options. By default, only published and unpublished tags are returned.
*
* @return array Tag data
*
* @since 3.1
*/
public static function tags($config = array('filter.published' => array(0, 1)))
{
$hash = md5(serialize($config));
$config = (array) $config;
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select('a.id, a.title, a.level, a.parent_id')
->from('#__tags AS a')
->where('a.parent_id > 0');
// Filter on the published state
if (isset($config['filter.published']))
{
if (is_numeric($config['filter.published']))
{
$query->where('a.published = ' . (int) $config['filter.published']);
}
elseif (is_array($config['filter.published']))
{
JArrayHelper::toInteger($config['filter.published']);
$query->where('a.published IN (' . implode(',', $config['filter.published']) . ')');
}
}
$query->order('a.lft');
$db->setQuery($query);
$items = $db->loadObjectList();
// Assemble the list options.
static::$items[$hash] = array();
foreach ($items as &$item)
{
$repeat = ($item->level - 1 >= 0) ? $item->level - 1 : 0;
$item->title = str_repeat('- ', $repeat) . $item->title;
static::$items[$hash][] = JHtml::_('select.option', $item->id, $item->title);
}
return static::$items[$hash];
}
/**
* This is just a proxy for the formbehavior.ajaxchosen method
*
* @param string $selector DOM id of the tag field
* @param boolean $allowCustom Flag to allow custom values
*
* @return void
*
* @since 3.1
*/
public static function ajaxfield($selector='#jform_tags', $allowCustom = true)
{
// Tags field ajax
$chosenAjaxSettings = new JRegistry(
array(
'selector' => $selector,
'type' => 'GET',
'url' => JUri::root() . 'index.php?option=com_tags&task=tags.searchAjax',
'dataType' => 'json',
'jsonTermKey' => 'like'
)
);
JHtml::_('formbehavior.ajaxchosen', $chosenAjaxSettings);
// Allow custom values ?
if ($allowCustom)
{
JFactory::getDocument()->addScriptDeclaration("
(function($){
$(document).ready(function () {
var customTagPrefix = '#new#';
// Method to add tags pressing enter
$('" . $selector . "_chzn input').keydown(function(event) {
// Tag is greater than 3 chars and enter pressed
if (this.value.length >= 3 && (event.which === 13 || event.which === 188)) {
// Search an highlighted result
var highlighted = $('" . $selector . "_chzn').find('li.active-result.highlighted').first();
// Add the highlighted option
if (event.which === 13 && highlighted.text() !== '')
{
// Extra check. If we have added a custom tag with this text remove it
var customOptionValue = customTagPrefix + highlighted.text();
$('" . $selector . " option').filter(function () { return $(this).val() == customOptionValue; }).remove();
// Select the highlighted result
var tagOption = $('" . $selector . " option').filter(function () { return $(this).html() == highlighted.text(); });
tagOption.attr('selected', 'selected');
}
// Add the custom tag option
else
{
var customTag = this.value;
// Extra check. Search if the custom tag already exists (typed faster than AJAX ready)
var tagOption = $('" . $selector . " option').filter(function () { return $(this).html() == customTag; });
if (tagOption.text() !== '')
{
tagOption.attr('selected', 'selected');
}
else
{
var option = $('<option>');
option.text(this.value).val(customTagPrefix + this.value);
option.attr('selected','selected');
// Append the option an repopulate the chosen field
$('" . $selector . "').append(option);
}
}
this.value = '';
$('" . $selector . "').trigger('liszt:updated');
event.preventDefault();
}
});
});
})(jQuery);
"
);
}
}
}

View File

@ -0,0 +1,80 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage HTML
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
/**
* HTML helper class for rendering telephone numbers.
*
* @package Joomla.Libraries
* @subpackage HTML
* @since 1.6
*/
abstract class JHtmlTel
{
/**
* Converts strings of integers into more readable telephone format
*
* By default, the ITU-T format will automatically be used.
* However, one of the allowed unit types may also be used instead.
*
* @param integer $number The integers in a phone number with dot separated country code
* ccc.nnnnnnn where ccc represents country code and nnn represents the local number.
* @param string $displayplan The numbering plan used to display the numbers.
*
* @return string The formatted telephone number.
*
* @see JFormRuleTel
* @since 1.6
*/
public static function tel($number, $displayplan)
{
$number = explode('.', $number);
$countrycode = $number[0];
$number = $number[1];
if ($displayplan == 'ITU-T' || $displayplan == 'International' || $displayplan == 'int' || $displayplan == 'missdn' || $displayplan == null)
{
$display[0] = '+';
$display[1] = $countrycode;
$display[2] = ' ';
$display[3] = implode(str_split($number, 2), ' ');
}
elseif ($displayplan == 'NANP' || $displayplan == 'northamerica' || $displayplan == 'US')
{
$display[0] = '(';
$display[1] = substr($number, 0, 3);
$display[2] = ') ';
$display[3] = substr($number, 3, 3);
$display[4] = '-';
$display[5] = substr($number, 6, 4);
}
elseif ($displayplan == 'EPP' || $displayplan == 'IETF')
{
$display[0] = '+';
$display[1] = $countrycode;
$display[2] = '.';
$display[3] = $number;
}
elseif ($displayplan == 'ARPA' || $displayplan == 'ENUM')
{
$number = implode(str_split(strrev($number), 1), '.');
$display[0] = '+';
$display[1] = $number;
$display[2] = '.';
$display[3] = $countrycode;
$display[4] = '.e164.arpa';
}
$display = implode($display, '');
return $display;
}
}

View File

@ -0,0 +1,86 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage HTML
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
/**
* Utility class working with users
*
* @package Joomla.Libraries
* @subpackage HTML
* @since 2.5
*/
abstract class JHtmlUser
{
/**
* Displays a list of user groups.
*
* @param boolean $includeSuperAdmin true to include super admin groups, false to exclude them
*
* @return array An array containing a list of user groups.
*
* @since 2.5
*/
public static function groups($includeSuperAdmin = false)
{
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select('a.id AS value, a.title AS text, COUNT(DISTINCT b.id) AS level')
->from($db->quoteName('#__usergroups') . ' AS a')
->join('LEFT', $db->quoteName('#__usergroups') . ' AS b ON a.lft > b.lft AND a.rgt < b.rgt')
->group('a.id, a.title, a.lft, a.rgt')
->order('a.lft ASC');
$db->setQuery($query);
$options = $db->loadObjectList();
for ($i = 0, $n = count($options); $i < $n; $i++)
{
$options[$i]->text = str_repeat('- ', $options[$i]->level) . $options[$i]->text;
$groups[] = JHtml::_('select.option', $options[$i]->value, $options[$i]->text);
}
// Exclude super admin groups if requested
if (!$includeSuperAdmin)
{
$filteredGroups = array();
foreach ($groups as $group)
{
if (!JAccess::checkGroup($group->value, 'core.admin'))
{
$filteredGroups[] = $group;
}
}
$groups = $filteredGroups;
}
return $groups;
}
/**
* Get a list of users.
*
* @return string
*
* @since 2.5
*/
public static function userlist()
{
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select('a.id AS value, a.name AS text')
->from('#__users AS a')
->where('a.block = 0')
->order('a.name');
$db->setQuery($query);
$items = $db->loadObjectList();
return $items;
}
}

1
libraries/cms/index.html Normal file
View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,814 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage Installer
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
jimport('joomla.base.adapterinstance');
jimport('joomla.filesystem.folder');
/**
* File installer
*
* @package Joomla.Libraries
* @subpackage Installer
* @since 3.1
*/
class JInstallerAdapterFile extends JAdapterInstance
{
protected $route = 'install';
/**
* Custom loadLanguage method
*
* @param string $path The path on which to find language files.
*
* @return void
*
* @since 3.1
*/
public function loadLanguage($path)
{
$this->manifest = $this->parent->getManifest();
$extension = 'files_' . str_replace('files_', '', strtolower(JFilterInput::getInstance()->clean((string) $this->manifest->name, 'cmd')));
$lang = JFactory::getLanguage();
$source = $path;
$lang->load($extension . '.sys', $source, null, false, false)
|| $lang->load($extension . '.sys', JPATH_SITE, null, false, false)
|| $lang->load($extension . '.sys', $source, $lang->getDefault(), false, false)
|| $lang->load($extension . '.sys', JPATH_SITE, $lang->getDefault(), false, false);
}
/**
* Custom install method
*
* @return boolean True on success
*
* @since 3.1
*/
public function install()
{
// Get the extension manifest object
$this->manifest = $this->parent->getManifest();
/*
* ---------------------------------------------------------------------------------------------
* Manifest Document Setup Section
* ---------------------------------------------------------------------------------------------
*/
// Set the extension's name
$name = JFilterInput::getInstance()->clean((string) $this->manifest->name, 'string');
$this->set('name', $name);
// Set element
$manifestPath = JPath::clean($this->parent->getPath('manifest'));
$element = preg_replace('/\.xml/', '', basename($manifestPath));
$this->set('element', $element);
// Get the component description
$description = (string) $this->manifest->description;
if ($description)
{
$this->parent->set('message', JText::_($description));
}
else
{
$this->parent->set('message', '');
}
// Check if the extension by the same name is already installed
if ($this->extensionExistsInSystem($element))
{
// Package with same name already exists
if (!$this->parent->isOverwrite())
{
// We're not overwriting so abort
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_FILE_SAME_NAME'));
return false;
}
else
{
// Swap to the update route
$this->route = 'update';
}
}
// Set the file root path
if ($name == 'files_joomla')
{
// If we are updating the Joomla core, set the root path to the root of Joomla
$this->parent->setPath('extension_root', JPATH_ROOT);
}
else
{
$this->parent->setPath('extension_root', JPATH_MANIFESTS . '/files/' . $this->get('element'));
}
/**
* ---------------------------------------------------------------------------------------------
* Installer Trigger Loading
* ---------------------------------------------------------------------------------------------
*/
// If there is an manifest class file, lets load it; we'll copy it later (don't have dest yet)
$this->scriptElement = $this->manifest->scriptfile;
$manifestScript = (string) $this->manifest->scriptfile;
if ($manifestScript)
{
$manifestScriptFile = $this->parent->getPath('source') . '/' . $manifestScript;
if (is_file($manifestScriptFile))
{
// Load the file
include_once $manifestScriptFile;
}
// Set the class name
$classname = $element . 'InstallerScript';
if (class_exists($classname))
{
// Create a new instance
$this->parent->manifestClass = new $classname($this);
// And set this so we can copy it later
$this->set('manifest_script', $manifestScript);
}
}
// Run preflight if possible (since we know we're not an update)
ob_start();
ob_implicit_flush(false);
if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'preflight'))
{
if ($this->parent->manifestClass->preflight($this->route, $this) === false)
{
// Install failed, rollback changes
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_FILE_INSTALL_CUSTOM_INSTALL_FAILURE'));
return false;
}
}
// Create msg object; first use here
$msg = ob_get_contents();
ob_end_clean();
// Populate File and Folder List to copy
$this->populateFilesAndFolderList();
/*
* ---------------------------------------------------------------------------------------------
* Filesystem Processing Section
* ---------------------------------------------------------------------------------------------
*/
// Now that we have folder list, lets start creating them
foreach ($this->folderList as $folder)
{
if (!JFolder::exists($folder))
{
if (!$created = JFolder::create($folder))
{
JLog::add(JText::sprintf('JLIB_INSTALLER_ABORT_FILE_INSTALL_FAIL_SOURCE_DIRECTORY', $folder), JLog::WARNING, 'jerror');
// If installation fails, rollback
$this->parent->abort();
return false;
}
// Since we created a directory and will want to remove it if we have to roll back.
// The installation due to some errors, let's add it to the installation step stack.
if ($created)
{
$this->parent->pushStep(array('type' => 'folder', 'path' => $folder));
}
}
}
// Now that we have file list, let's start copying them
$this->parent->copyFiles($this->fileList);
// Parse optional tags
$this->parent->parseLanguages($this->manifest->languages);
/**
* ---------------------------------------------------------------------------------------------
* Finalization and Cleanup Section
* ---------------------------------------------------------------------------------------------
*/
// Get a database connector object
$db = $this->parent->getDbo();
/*
* Check to see if a file extension by the same name is already installed
* If it is, then update the table because if the files aren't there
* we can assume that it was (badly) uninstalled
* If it isn't, add an entry to extensions
*/
$query = $db->getQuery(true)
->select($db->quoteName('extension_id'))
->from($db->quoteName('#__extensions'))
->where($db->quoteName('type') . ' = ' . $db->quote('file'))
->where($db->quoteName('element') . ' = ' . $db->quote($element));
$db->setQuery($query);
try
{
$db->execute();
}
catch (RuntimeException $e)
{
// Install failed, roll back changes
$this->parent->abort(
JText::sprintf('JLIB_INSTALLER_ABORT_FILE_ROLLBACK', JText::_('JLIB_INSTALLER_' . $this->route), $db->stderr(true))
);
return false;
}
$id = $db->loadResult();
$row = JTable::getInstance('extension');
if ($id)
{
// Load the entry and update the manifest_cache
$row->load($id);
// Update name
$row->set('name', $this->get('name'));
// Update manifest
$row->manifest_cache = $this->parent->generateManifestCache();
if (!$row->store())
{
// Install failed, roll back changes
$this->parent->abort(
JText::sprintf('JLIB_INSTALLER_ABORT_FILE_ROLLBACK', JText::_('JLIB_INSTALLER_' . $this->route), $db->stderr(true))
);
return false;
}
}
else
{
// Add an entry to the extension table with a whole heap of defaults
$row->set('name', $this->get('name'));
$row->set('type', 'file');
$row->set('element', $this->get('element'));
// There is no folder for files so leave it blank
$row->set('folder', '');
$row->set('enabled', 1);
$row->set('protected', 0);
$row->set('access', 0);
$row->set('client_id', 0);
$row->set('params', '');
$row->set('system_data', '');
$row->set('manifest_cache', $this->parent->generateManifestCache());
if (!$row->store())
{
// Install failed, roll back changes
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_FILE_INSTALL_ROLLBACK', $db->stderr(true)));
return false;
}
// Since we have created a module item, we add it to the installation step stack
// so that if we have to rollback the changes we can undo it.
$this->parent->pushStep(array('type' => 'extension', 'extension_id' => $row->extension_id));
}
// Let's run the queries for the file
if (strtolower($this->route) == 'install')
{
$result = $this->parent->parseSQLFiles($this->manifest->install->sql);
if ($result === false)
{
// Install failed, rollback changes
$this->parent->abort(
JText::sprintf('JLIB_INSTALLER_ABORT_FILE_INSTALL_SQL_ERROR', JText::_('JLIB_INSTALLER_' . $this->route), $db->stderr(true))
);
return false;
}
// Set the schema version to be the latest update version
if ($this->manifest->update)
{
$this->parent->setSchemaVersion($this->manifest->update->schemas, $row->extension_id);
}
}
elseif (strtolower($this->route) == 'update')
{
if ($this->manifest->update)
{
$result = $this->parent->parseSchemaUpdates($this->manifest->update->schemas, $row->extension_id);
if ($result === false)
{
// Install failed, rollback changes
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_FILE_UPDATE_SQL_ERROR', $db->stderr(true)));
return false;
}
}
}
// Try to run the script file's custom method based on the route
ob_start();
ob_implicit_flush(false);
if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, $this->route))
{
if ($this->parent->manifestClass->{$this->route}($this) === false)
{
// Install failed, rollback changes
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_FILE_INSTALL_CUSTOM_INSTALL_FAILURE'));
return false;
}
}
// Append messages
$msg .= ob_get_contents();
ob_end_clean();
// Lastly, we will copy the manifest file to its appropriate place.
$manifest = array();
$manifest['src'] = $this->parent->getPath('manifest');
$manifest['dest'] = JPATH_MANIFESTS . '/files/' . basename($this->parent->getPath('manifest'));
if (!$this->parent->copyFiles(array($manifest), true))
{
// Install failed, rollback changes
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_FILE_INSTALL_COPY_SETUP'));
return false;
}
// If there is a manifest script, let's copy it.
if ($this->get('manifest_script'))
{
// First, we have to create a folder for the script if one isn't present
if (!file_exists($this->parent->getPath('extension_root')))
{
JFolder::create($this->parent->getPath('extension_root'));
}
$path['src'] = $this->parent->getPath('source') . '/' . $this->get('manifest_script');
$path['dest'] = $this->parent->getPath('extension_root') . '/' . $this->get('manifest_script');
if (!file_exists($path['dest']) || $this->parent->isOverwrite())
{
if (!$this->parent->copyFiles(array($path)))
{
// Install failed, rollback changes
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_PACKAGE_INSTALL_MANIFEST'));
return false;
}
}
}
// Clobber any possible pending updates
$update = JTable::getInstance('update');
$uid = $update->find(
array('element' => $this->get('element'), 'type' => 'file', 'client_id' => '', 'folder' => '')
);
if ($uid)
{
$update->delete($uid);
}
// And now we run the postflight
ob_start();
ob_implicit_flush(false);
if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'postflight'))
{
$this->parent->manifestClass->postflight($this->route, $this);
}
// Append messages
$msg .= ob_get_contents();
ob_end_clean();
if ($msg != '')
{
$this->parent->set('extension_message', $msg);
}
return $row->get('extension_id');
}
/**
* Custom update method
*
* @return boolean True on success
*
* @since 3.1
*/
public function update()
{
// Set the overwrite setting
$this->parent->setOverwrite(true);
$this->parent->setUpgrade(true);
$this->route = 'update';
// ...and adds new files
return $this->install();
}
/**
* Custom uninstall method
*
* @param string $id The id of the file to uninstall
*
* @return boolean True on success
*
* @since 3.1
*/
public function uninstall($id)
{
$row = JTable::getInstance('extension');
if (!$row->load($id))
{
JLog::add(JText::_('JLIB_INSTALLER_ERROR_FILE_UNINSTALL_LOAD_ENTRY'), JLog::WARNING, 'jerror');
return false;
}
if ($row->protected)
{
JLog::add(JText::_('JLIB_INSTALLER_ERROR_FILE_UNINSTALL_WARNCOREFILE'), JLog::WARNING, 'jerror');
return false;
}
$retval = true;
$manifestFile = JPATH_MANIFESTS . '/files/' . $row->element . '.xml';
// Because files may not have their own folders we cannot use the standard method of finding an installation manifest
if (file_exists($manifestFile))
{
// Set the files root path
$this->parent->setPath('extension_root', JPATH_MANIFESTS . '/files/' . $row->element);
$xml = simplexml_load_file($manifestFile);
// If we cannot load the XML file return null
if (!$xml)
{
JLog::add(JText::_('JLIB_INSTALLER_ERROR_FILE_UNINSTALL_LOAD_MANIFEST'), JLog::WARNING, 'jerror');
return false;
}
// Check for a valid XML root tag.
if ($xml->getName() != 'extension')
{
JLog::add(JText::_('JLIB_INSTALLER_ERROR_FILE_UNINSTALL_INVALID_MANIFEST'), JLog::WARNING, 'jerror');
return false;
}
$this->manifest = $xml;
// If there is an manifest class file, let's load it
$this->scriptElement = $this->manifest->scriptfile;
$manifestScript = (string) $this->manifest->scriptfile;
if ($manifestScript)
{
$manifestScriptFile = $this->parent->getPath('extension_root') . '/' . $manifestScript;
if (is_file($manifestScriptFile))
{
// Load the file
include_once $manifestScriptFile;
}
// Set the class name
$classname = $row->element . 'InstallerScript';
if (class_exists($classname))
{
// Create a new instance
$this->parent->manifestClass = new $classname($this);
// And set this so we can copy it later
$this->set('manifest_script', $manifestScript);
}
}
ob_start();
ob_implicit_flush(false);
// Run uninstall if possible
if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'uninstall'))
{
$this->parent->manifestClass->uninstall($this);
}
$msg = ob_get_contents();
ob_end_clean();
if ($msg != '')
{
$this->parent->set('extension_message', $msg);
}
$db = JFactory::getDbo();
// Let's run the uninstall queries for the extension
$result = $this->parent->parseSQLFiles($this->manifest->uninstall->sql);
if ($result === false)
{
// Install failed, rollback changes
JLog::add(JText::sprintf('JLIB_INSTALLER_ERROR_FILE_UNINSTALL_SQL_ERROR', $db->stderr(true)), JLog::WARNING, 'jerror');
$retval = false;
}
// Remove the schema version
$query = $db->getQuery(true)
->delete('#__schemas')
->where('extension_id = ' . $row->extension_id);
$db->setQuery($query);
$db->execute();
// Loop through all elements and get list of files and folders
foreach ($xml->fileset->files as $eFiles)
{
$target = (string) $eFiles->attributes()->target;
// Create folder path
if (empty($target))
{
$targetFolder = JPATH_ROOT;
}
else
{
$targetFolder = JPATH_ROOT . '/' . $target;
}
$folderList = array();
// Check if all children exists
if (count($eFiles->children()) > 0)
{
// Loop through all filenames elements
foreach ($eFiles->children() as $eFileName)
{
if ($eFileName->getName() == 'folder')
{
$folderList[] = $targetFolder . '/' . $eFileName;
}
else
{
$fileName = $targetFolder . '/' . $eFileName;
JFile::delete($fileName);
}
}
}
// Delete any folders that don't have any content in them.
foreach ($folderList as $folder)
{
$files = JFolder::files($folder);
if (!count($files))
{
JFolder::delete($folder);
}
}
}
JFile::delete($manifestFile);
// Lastly, remove the extension_root
$folder = $this->parent->getPath('extension_root');
if (JFolder::exists($folder))
{
JFolder::delete($folder);
}
}
else
{
JLog::add(JText::_('JLIB_INSTALLER_ERROR_FILE_UNINSTALL_INVALID_NOTFOUND_MANIFEST'), JLog::WARNING, 'jerror');
// Delete the row because its broken
$row->delete();
return false;
}
$this->parent->removeFiles($xml->languages);
$row->delete();
return $retval;
}
/**
* Function used to check if extension is already installed
*
* @param string $extension The element name of the extension to install
*
* @return boolean True if extension exists
*
* @since 3.1
*/
protected function extensionExistsInSystem($extension = null)
{
// Get a database connector object
$db = $this->parent->getDBO();
$query = $db->getQuery(true)
->select($db->quoteName('extension_id'))
->from($db->quoteName('#__extensions'))
->where($db->quoteName('type') . ' = ' . $db->quote('file'))
->where($db->quoteName('element') . ' = ' . $db->quote($extension));
$db->setQuery($query);
try
{
$db->execute();
}
catch (RuntimeException $e)
{
// Install failed, roll back changes
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_FILE_ROLLBACK', $db->stderr(true)));
return false;
}
$id = $db->loadResult();
if (empty($id))
{
return false;
}
return true;
}
/**
* Function used to populate files and folder list
*
* @return boolean none
*
* @since 3.1
*/
protected function populateFilesAndFolderList()
{
// Initialise variable
$this->folderList = array();
$this->fileList = array();
// Set root folder names
$packagePath = $this->parent->getPath('source');
$jRootPath = JPath::clean(JPATH_ROOT);
// Loop through all elements and get list of files and folders
foreach ($this->manifest->fileset->files as $eFiles)
{
// Check if the element is files element
$folder = (string) $eFiles->attributes()->folder;
$target = (string) $eFiles->attributes()->target;
// Split folder names into array to get folder names. This will help in creating folders
$arrList = preg_split("#/|\\/#", $target);
$folderName = $jRootPath;
foreach ($arrList as $dir)
{
if (empty($dir))
{
continue;
}
$folderName .= '/' . $dir;
// Check if folder exists, if not then add to the array for folder creation
if (!JFolder::exists($folderName))
{
array_push($this->folderList, $folderName);
}
}
// Create folder path
$sourceFolder = empty($folder) ? $packagePath : $packagePath . '/' . $folder;
$targetFolder = empty($target) ? $jRootPath : $jRootPath . '/' . $target;
// Check if source folder exists
if (!JFolder::exists($sourceFolder))
{
JLog::add(JText::sprintf('JLIB_INSTALLER_ABORT_FILE_INSTALL_FAIL_SOURCE_DIRECTORY', $sourceFolder), JLog::WARNING, 'jerror');
// If installation fails, rollback
$this->parent->abort();
return false;
}
// Check if all children exists
if (count($eFiles->children()))
{
// Loop through all filenames elements
foreach ($eFiles->children() as $eFileName)
{
$path['src'] = $sourceFolder . '/' . $eFileName;
$path['dest'] = $targetFolder . '/' . $eFileName;
$path['type'] = 'file';
if ($eFileName->getName() == 'folder')
{
$folderName = $targetFolder . '/' . $eFileName;
array_push($this->folderList, $folderName);
$path['type'] = 'folder';
}
array_push($this->fileList, $path);
}
}
else
{
$files = JFolder::files($sourceFolder);
foreach ($files as $file)
{
$path['src'] = $sourceFolder . '/' . $file;
$path['dest'] = $targetFolder . '/' . $file;
array_push($this->fileList, $path);
}
}
}
}
/**
* Refreshes the extension table cache
*
* @return boolean result of operation, true if updated, false on failure
*
* @since 3.1
*/
public function refreshManifestCache()
{
// Need to find to find where the XML file is since we don't store this normally
$manifestPath = JPATH_MANIFESTS . '/files/' . $this->parent->extension->element . '.xml';
$this->parent->manifest = $this->parent->isManifest($manifestPath);
$this->parent->setPath('manifest', $manifestPath);
$manifest_details = JInstaller::parseXMLInstallFile($this->parent->getPath('manifest'));
$this->parent->extension->manifest_cache = json_encode($manifest_details);
$this->parent->extension->name = $manifest_details['name'];
try
{
return $this->parent->extension->store();
}
catch (RuntimeException $e)
{
JLog::add(JText::_('JLIB_INSTALLER_ERROR_PACK_REFRESH_MANIFEST_CACHE'), JLog::WARNING, 'jerror');
return false;
}
}
}
/**
* Deprecated class placeholder. You should use JInstallerAdapterFile instead.
*
* @package Joomla.Libraries
* @subpackage Installer
* @since 3.1
* @deprecated 4.0
* @codeCoverageIgnore
*/
class JInstallerFile extends JInstallerAdapterFile
{
}

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1,670 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage Installer
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
jimport('joomla.base.adapterinstance');
jimport('joomla.filesystem.folder');
/**
* Language installer
*
* @package Joomla.Libraries
* @subpackage Installer
* @since 3.1
*/
class JInstallerAdapterLanguage extends JAdapterInstance
{
/**
* Core language pack flag
*
* @var boolean
* @since 12.1
*/
protected $core = false;
/**
* Custom install method
*
* Note: This behaves badly due to hacks made in the middle of 1.5.x to add
* the ability to install multiple distinct packs in one install. The
* preferred method is to use a package to install multiple language packs.
*
* @return boolean True on success
*
* @since 3.1
*/
public function install()
{
$source = $this->parent->getPath('source');
if (!$source)
{
$this->parent
->setPath(
'source',
($this->parent->extension->client_id ? JPATH_ADMINISTRATOR : JPATH_SITE) . '/language/' . $this->parent->extension->element
);
}
$this->manifest = $this->parent->getManifest();
// Get the client application target
if ($cname = (string) $this->manifest->attributes()->client)
{
// Attempt to map the client to a base path
$client = JApplicationHelper::getClientInfo($cname, true);
if ($client === null)
{
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT', JText::sprintf('JLIB_INSTALLER_ERROR_UNKNOWN_CLIENT_TYPE', $cname)));
return false;
}
$basePath = $client->path;
$clientId = $client->id;
$element = $this->manifest->files;
return $this->_install($cname, $basePath, $clientId, $element);
}
else
{
// No client attribute was found so we assume the site as the client
$cname = 'site';
$basePath = JPATH_SITE;
$clientId = 0;
$element = $this->manifest->files;
return $this->_install($cname, $basePath, $clientId, $element);
}
}
/**
* Install function that is designed to handle individual clients
*
* @param string $cname Cname @todo: not used
* @param string $basePath The base name.
* @param integer $clientId The client id.
* @param object &$element The XML element.
*
* @return boolean
*
* @since 3.1
*/
protected function _install($cname, $basePath, $clientId, &$element)
{
$this->manifest = $this->parent->getManifest();
// Get the language name
// Set the extensions name
$name = JFilterInput::getInstance()->clean((string) $this->manifest->name, 'cmd');
$this->set('name', $name);
// Get the Language tag [ISO tag, eg. en-GB]
$tag = (string) $this->manifest->tag;
// Check if we found the tag - if we didn't, we may be trying to install from an older language package
if (!$tag)
{
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT', JText::_('JLIB_INSTALLER_ERROR_NO_LANGUAGE_TAG')));
return false;
}
$this->set('tag', $tag);
// Set the language installation path
$this->parent->setPath('extension_site', $basePath . '/language/' . $tag);
// Do we have a meta file in the file list? In other words... is this a core language pack?
if ($element && count($element->children()))
{
$files = $element->children();
foreach ($files as $file)
{
if ((string) $file->attributes()->file == 'meta')
{
$this->core = true;
break;
}
}
}
// If the language directory does not exist, let's create it
$created = false;
if (!file_exists($this->parent->getPath('extension_site')))
{
if (!$created = JFolder::create($this->parent->getPath('extension_site')))
{
$this->parent
->abort(
JText::sprintf(
'JLIB_INSTALLER_ABORT',
JText::sprintf('JLIB_INSTALLER_ERROR_CREATE_FOLDER_FAILED', $this->parent->getPath('extension_site'))
)
);
return false;
}
}
else
{
// Look for an update function or update tag
$updateElement = $this->manifest->update;
// Upgrade manually set or update tag detected
if ($this->parent->isUpgrade() || $updateElement)
{
// Transfer control to the update function
return $this->update();
}
elseif (!$this->parent->isOverwrite())
{
// Overwrite is set
// We didn't have overwrite set, find an update function or find an update tag so lets call it safe
if (file_exists($this->parent->getPath('extension_site')))
{
// If the site exists say so.
JLog::add(
JText::sprintf('JLIB_INSTALLER_ABORT', JText::sprintf('JLIB_INSTALLER_ERROR_FOLDER_IN_USE', $this->parent->getPath('extension_site'))),
JLog::WARNING, 'jerror'
);
}
else
{
// If the admin exists say so.
JLog::add(
JText::sprintf('JLIB_INSTALLER_ABORT', JText::sprintf('JLIB_INSTALLER_ERROR_FOLDER_IN_USE', $this->parent->getPath('extension_administrator'))),
JLog::WARNING, 'jerror'
);
}
return false;
}
}
/*
* If we created the language directory we will want to remove it if we
* have to roll back the installation, so let's add it to the installation
* step stack
*/
if ($created)
{
$this->parent->pushStep(array('type' => 'folder', 'path' => $this->parent->getPath('extension_site')));
}
// Copy all the necessary files
if ($this->parent->parseFiles($element) === false)
{
// Install failed, rollback changes
$this->parent->abort();
return false;
}
// Parse optional tags
$this->parent->parseMedia($this->manifest->media);
// Copy all the necessary font files to the common pdf_fonts directory
$this->parent->setPath('extension_site', $basePath . '/language/pdf_fonts');
$overwrite = $this->parent->setOverwrite(true);
if ($this->parent->parseFiles($this->manifest->fonts) === false)
{
// Install failed, rollback changes
$this->parent->abort();
return false;
}
$this->parent->setOverwrite($overwrite);
// Get the language description
$description = (string) $this->manifest->description;
if ($description)
{
$this->parent->set('message', JText::_($description));
}
else
{
$this->parent->set('message', '');
}
// Add an entry to the extension table with a whole heap of defaults
$row = JTable::getInstance('extension');
$row->set('name', $this->get('name'));
$row->set('type', 'language');
$row->set('element', $this->get('tag'));
// There is no folder for languages
$row->set('folder', '');
$row->set('enabled', 1);
$row->set('protected', 0);
$row->set('access', 0);
$row->set('client_id', $clientId);
$row->set('params', $this->parent->getParams());
$row->set('manifest_cache', $this->parent->generateManifestCache());
if (!$row->store())
{
// Install failed, roll back changes
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT', $row->getError()));
return false;
}
// Clobber any possible pending updates
$update = JTable::getInstance('update');
$uid = $update->find(array('element' => $this->get('tag'), 'type' => 'language', 'client_id' => '', 'folder' => ''));
if ($uid)
{
$update->delete($uid);
}
return $row->get('extension_id');
}
/**
* Custom update method
*
* @return boolean True on success, false on failure
*
* @since 3.1
*/
public function update()
{
$xml = $this->parent->getManifest();
$this->manifest = $xml;
$cname = $xml->attributes()->client;
// Attempt to map the client to a base path
$client = JApplicationHelper::getClientInfo($cname, true);
if ($client === null || (empty($cname) && $cname !== 0))
{
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT', JText::sprintf('JLIB_INSTALLER_ERROR_UNKNOWN_CLIENT_TYPE', $cname)));
return false;
}
$basePath = $client->path;
$clientId = $client->id;
// Get the language name
// Set the extensions name
$name = (string) $this->manifest->name;
$name = JFilterInput::getInstance()->clean($name, 'cmd');
$this->set('name', $name);
// Get the Language tag [ISO tag, eg. en-GB]
$tag = (string) $xml->tag;
// Check if we found the tag - if we didn't, we may be trying to install from an older language package
if (!$tag)
{
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT', JText::_('JLIB_INSTALLER_ERROR_NO_LANGUAGE_TAG')));
return false;
}
$this->set('tag', $tag);
// Set the language installation path
$this->parent->setPath('extension_site', $basePath . '/language/' . $tag);
// Do we have a meta file in the file list? In other words... is this a core language pack?
if (count($xml->files->children()))
{
foreach ($xml->files->children() as $file)
{
if ((string) $file->attributes()->file == 'meta')
{
$this->core = true;
break;
}
}
}
// Copy all the necessary files
if ($this->parent->parseFiles($xml->files) === false)
{
// Install failed, rollback changes
$this->parent->abort();
return false;
}
// Parse optional tags
$this->parent->parseMedia($xml->media);
// Copy all the necessary font files to the common pdf_fonts directory
$this->parent->setPath('extension_site', $basePath . '/language/pdf_fonts');
$overwrite = $this->parent->setOverwrite(true);
if ($this->parent->parseFiles($xml->fonts) === false)
{
// Install failed, rollback changes
$this->parent->abort();
return false;
}
$this->parent->setOverwrite($overwrite);
// Get the language description and set it as message
$this->parent->set('message', (string) $xml->description);
/**
* ---------------------------------------------------------------------------------------------
* Finalization and Cleanup Section
* ---------------------------------------------------------------------------------------------
*/
// Clobber any possible pending updates
$update = JTable::getInstance('update');
$uid = $update->find(array('element' => $this->get('tag'), 'type' => 'language', 'client_id' => $clientId));
if ($uid)
{
$update->delete($uid);
}
// Update an entry to the extension table
$row = JTable::getInstance('extension');
$eid = $row->find(array('element' => strtolower($this->get('tag')), 'type' => 'language', 'client_id' => $clientId));
if ($eid)
{
$row->load($eid);
}
else
{
// Set the defaults
// There is no folder for language
$row->set('folder', '');
$row->set('enabled', 1);
$row->set('protected', 0);
$row->set('access', 0);
$row->set('client_id', $clientId);
$row->set('params', $this->parent->getParams());
}
$row->set('name', $this->get('name'));
$row->set('type', 'language');
$row->set('element', $this->get('tag'));
$row->set('manifest_cache', $this->parent->generateManifestCache());
if (!$row->store())
{
// Install failed, roll back changes
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT', $row->getError()));
return false;
}
return $row->get('extension_id');
}
/**
* Custom uninstall method
*
* @param string $eid The tag of the language to uninstall
*
* @return mixed Return value for uninstall method in component uninstall file
*
* @since 3.1
*/
public function uninstall($eid)
{
// Load up the extension details
$extension = JTable::getInstance('extension');
$extension->load($eid);
// Grab a copy of the client details
$client = JApplicationHelper::getClientInfo($extension->get('client_id'));
// Check the element isn't blank to prevent nuking the languages directory...just in case
$element = $extension->get('element');
if (empty($element))
{
JLog::add(JText::_('JLIB_INSTALLER_ERROR_LANG_UNINSTALL_ELEMENT_EMPTY'), JLog::WARNING, 'jerror');
return false;
}
// Check that the language is not protected, Normally en-GB.
$protected = $extension->get('protected');
if ($protected == 1)
{
JLog::add(JText::_('JLIB_INSTALLER_ERROR_LANG_UNINSTALL_PROTECTED'), JLog::WARNING, 'jerror');
return false;
}
// Verify that it's not the default language for that client
$params = JComponentHelper::getParams('com_languages');
if ($params->get($client->name) == $element)
{
JLog::add(JText::_('JLIB_INSTALLER_ERROR_LANG_UNINSTALL_DEFAULT'), JLog::WARNING, 'jerror');
return false;
}
// Construct the path from the client, the language and the extension element name
$path = $client->path . '/language/' . $element;
// Get the package manifest object and remove media
$this->parent->setPath('source', $path);
// We do findManifest to avoid problem when uninstalling a list of extension: getManifest cache its manifest file
$this->parent->findManifest();
$this->manifest = $this->parent->getManifest();
$this->parent->removeFiles($this->manifest->media);
// Check it exists
if (!JFolder::exists($path))
{
// If the folder doesn't exist lets just nuke the row as well and presume the user killed it for us
$extension->delete();
JLog::add(JText::_('JLIB_INSTALLER_ERROR_LANG_UNINSTALL_PATH_EMPTY'), JLog::WARNING, 'jerror');
return false;
}
if (!JFolder::delete($path))
{
// If deleting failed we'll leave the extension entry in tact just in case
JLog::add(JText::_('JLIB_INSTALLER_ERROR_LANG_UNINSTALL_DIRECTORY'), JLog::WARNING, 'jerror');
return false;
}
// Remove the extension table entry
$extension->delete();
// Setting the language of users which have this language as the default language
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->from('#__users')
->select('*');
$db->setQuery($query);
$users = $db->loadObjectList();
if ($client->name == 'administrator')
{
$param_name = 'admin_language';
}
else
{
$param_name = 'language';
}
$count = 0;
foreach ($users as $user)
{
$registry = new JRegistry;
$registry->loadString($user->params);
if ($registry->get($param_name) == $element)
{
$registry->set($param_name, '');
$query->clear()
->update('#__users')
->set('params=' . $db->quote($registry))
->where('id=' . (int) $user->id);
$db->setQuery($query);
$db->execute();
$count++;
}
}
if (!empty($count))
{
JLog::add(JText::plural('JLIB_INSTALLER_NOTICE_LANG_RESET_USERS', $count), JLog::NOTICE, 'jerror');
}
// All done!
return true;
}
/**
* Custom discover method
* Finds language files
*
* @return boolean True on success
*
* @since 3.1
*/
public function discover()
{
$results = array();
$site_languages = JFolder::folders(JPATH_SITE . '/language');
$admin_languages = JFolder::folders(JPATH_ADMINISTRATOR . '/language');
foreach ($site_languages as $language)
{
if (file_exists(JPATH_SITE . '/language/' . $language . '/' . $language . '.xml'))
{
$manifest_details = JInstaller::parseXMLInstallFile(JPATH_SITE . '/language/' . $language . '/' . $language . '.xml');
$extension = JTable::getInstance('extension');
$extension->set('type', 'language');
$extension->set('client_id', 0);
$extension->set('element', $language);
$extension->set('folder', '');
$extension->set('name', $language);
$extension->set('state', -1);
$extension->set('manifest_cache', json_encode($manifest_details));
$extension->set('params', '{}');
$results[] = $extension;
}
}
foreach ($admin_languages as $language)
{
if (file_exists(JPATH_ADMINISTRATOR . '/language/' . $language . '/' . $language . '.xml'))
{
$manifest_details = JInstaller::parseXMLInstallFile(JPATH_ADMINISTRATOR . '/language/' . $language . '/' . $language . '.xml');
$extension = JTable::getInstance('extension');
$extension->set('type', 'language');
$extension->set('client_id', 1);
$extension->set('element', $language);
$extension->set('folder', '');
$extension->set('name', $language);
$extension->set('state', -1);
$extension->set('manifest_cache', json_encode($manifest_details));
$extension->set('params', '{}');
$results[] = $extension;
}
}
return $results;
}
/**
* Custom discover install method
* Basically updates the manifest cache and leaves everything alone
*
* @return integer The extension id
*
* @since 3.1
*/
public function discover_install()
{
// Need to find to find where the XML file is since we don't store this normally
$client = JApplicationHelper::getClientInfo($this->parent->extension->client_id);
$short_element = $this->parent->extension->element;
$manifestPath = $client->path . '/language/' . $short_element . '/' . $short_element . '.xml';
$this->parent->manifest = $this->parent->isManifest($manifestPath);
$this->parent->setPath('manifest', $manifestPath);
$this->parent->setPath('source', $client->path . '/language/' . $short_element);
$this->parent->setPath('extension_root', $this->parent->getPath('source'));
$manifest_details = JInstaller::parseXMLInstallFile($this->parent->getPath('manifest'));
$this->parent->extension->manifest_cache = json_encode($manifest_details);
$this->parent->extension->state = 0;
$this->parent->extension->name = $manifest_details['name'];
$this->parent->extension->enabled = 1;
// @todo remove code: $this->parent->extension->params = $this->parent->getParams();
try
{
$this->parent->extension->store();
}
catch (RuntimeException $e)
{
JLog::add(JText::_('JLIB_INSTALLER_ERROR_LANG_DISCOVER_STORE_DETAILS'), JLog::WARNING, 'jerror');
return false;
}
return $this->parent->extension->get('extension_id');
}
/**
* Refreshes the extension table cache
*
* @return boolean result of operation, true if updated, false on failure
*
* @since 3.1
*/
public function refreshManifestCache()
{
$client = JApplicationHelper::getClientInfo($this->parent->extension->client_id);
$manifestPath = $client->path . '/language/' . $this->parent->extension->element . '/' . $this->parent->extension->element . '.xml';
$this->parent->manifest = $this->parent->isManifest($manifestPath);
$this->parent->setPath('manifest', $manifestPath);
$manifest_details = JInstaller::parseXMLInstallFile($this->parent->getPath('manifest'));
$this->parent->extension->manifest_cache = json_encode($manifest_details);
$this->parent->extension->name = $manifest_details['name'];
if ($this->parent->extension->store())
{
return true;
}
else
{
JLog::add(JText::_('JLIB_INSTALLER_ERROR_MOD_REFRESH_MANIFEST_CACHE'), JLog::WARNING, 'jerror');
return false;
}
}
}
/**
* Deprecated class placeholder. You should use JInstallerAdapterLanguage instead.
*
* @package Joomla.Libraries
* @subpackage Installer
* @since 3.1
* @deprecated 4.0
* @codeCoverageIgnore
*/
class JInstallerLanguage extends JInstallerAdapterLanguage
{
}

View File

@ -0,0 +1,479 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage Installer
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
jimport('joomla.base.adapterinstance');
jimport('joomla.filesystem.folder');
/**
* Library installer
*
* @package Joomla.Libraries
* @subpackage Installer
* @since 3.1
*/
class JInstallerAdapterLibrary extends JAdapterInstance
{
/**
* Custom loadLanguage method
*
* @param string $path The path where to find language files.
*
* @return void
*
* @since 3.1
*/
public function loadLanguage($path = null)
{
$source = $this->parent->getPath('source');
if (!$source)
{
$this->parent->setPath('source', JPATH_PLATFORM . '/' . $this->parent->extension->element);
}
$this->manifest = $this->parent->getManifest();
$extension = 'lib_' . strtolower(JFilterInput::getInstance()->clean((string) $this->manifest->name, 'cmd'));
$name = strtolower((string) $this->manifest->libraryname);
$lang = JFactory::getLanguage();
$source = $path ? $path : JPATH_PLATFORM . "/$name";
$lang->load($extension . '.sys', $source, null, false, false)
|| $lang->load($extension . '.sys', JPATH_SITE, null, false, false)
|| $lang->load($extension . '.sys', $source, $lang->getDefault(), false, false)
|| $lang->load($extension . '.sys', JPATH_SITE, $lang->getDefault(), false, false);
}
/**
* Custom install method
*
* @return boolean True on success
*
* @since 3.1
*/
public function install()
{
// Get the extension manifest object
$this->manifest = $this->parent->getManifest();
/*
* ---------------------------------------------------------------------------------------------
* Manifest Document Setup Section
* ---------------------------------------------------------------------------------------------
*/
// Set the extension's name
$name = JFilterInput::getInstance()->clean((string) $this->manifest->name, 'string');
$element = str_replace('.xml', '', basename($this->parent->getPath('manifest')));
$this->set('name', $name);
$this->set('element', $element);
$db = $this->parent->getDbo();
$query = $db->getQuery(true)
->select($db->quoteName('extension_id'))
->from($db->quoteName('#__extensions'))
->where($db->quoteName('type') . ' = ' . $db->quote('library'))
->where($db->quoteName('element') . ' = ' . $db->quote($element));
$db->setQuery($query);
$result = $db->loadResult();
if ($result)
{
// Already installed, can we upgrade?
if ($this->parent->isOverwrite() || $this->parent->isUpgrade())
{
// We can upgrade, so uninstall the old one
$installer = new JInstaller; // we don't want to compromise this instance!
$installer->uninstall('library', $result);
}
else
{
// Abort the install, no upgrade possible
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_LIB_INSTALL_ALREADY_INSTALLED'));
return false;
}
}
// Get the library's description
$description = (string) $this->manifest->description;
if ($description)
{
$this->parent->set('message', JText::_($description));
}
else
{
$this->parent->set('message', '');
}
// Set the installation path
$group = (string) $this->manifest->libraryname;
if (!$group)
{
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_LIB_INSTALL_NOFILE'));
return false;
}
else
{
$this->parent->setPath('extension_root', JPATH_PLATFORM . '/' . implode(DIRECTORY_SEPARATOR, explode('/', $group)));
}
/*
* ---------------------------------------------------------------------------------------------
* Filesystem Processing Section
* ---------------------------------------------------------------------------------------------
*/
// If the library directory does not exist, let's create it
$created = false;
if (!file_exists($this->parent->getPath('extension_root')))
{
if (!$created = JFolder::create($this->parent->getPath('extension_root')))
{
$this->parent->abort(
JText::sprintf('JLIB_INSTALLER_ABORT_LIB_INSTALL_FAILED_TO_CREATE_DIRECTORY', $this->parent->getPath('extension_root'))
);
return false;
}
}
/*
* If we created the library directory and will want to remove it if we
* have to roll back the installation, let's add it to the installation
* step stack
*/
if ($created)
{
$this->parent->pushStep(array('type' => 'folder', 'path' => $this->parent->getPath('extension_root')));
}
// Copy all necessary files
if ($this->parent->parseFiles($this->manifest->files, -1) === false)
{
// Install failed, roll back changes
$this->parent->abort();
return false;
}
// Parse optional tags
$this->parent->parseLanguages($this->manifest->languages);
$this->parent->parseMedia($this->manifest->media);
// Extension Registration
$row = JTable::getInstance('extension');
$row->name = $this->get('name');
$row->type = 'library';
$row->element = $this->get('element');
// There is no folder for libraries
$row->folder = '';
$row->enabled = 1;
$row->protected = 0;
$row->access = 1;
$row->client_id = 0;
$row->params = $this->parent->getParams();
// Custom data
$row->custom_data = '';
$row->manifest_cache = $this->parent->generateManifestCache();
if (!$row->store())
{
// Install failed, roll back changes
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_LIB_INSTALL_ROLLBACK', $db->stderr(true)));
return false;
}
/**
* ---------------------------------------------------------------------------------------------
* Finalization and Cleanup Section
* ---------------------------------------------------------------------------------------------
*/
// Lastly, we will copy the manifest file to its appropriate place.
$manifest = array();
$manifest['src'] = $this->parent->getPath('manifest');
$manifest['dest'] = JPATH_MANIFESTS . '/libraries/' . basename($this->parent->getPath('manifest'));
if (!$this->parent->copyFiles(array($manifest), true))
{
// Install failed, rollback changes
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_LIB_INSTALL_COPY_SETUP'));
return false;
}
return $row->get('extension_id');
}
/**
* Custom update method
*
* @return boolean True on success
*
* @since 3.1
*/
public function update()
{
// Since this is just files, an update removes old files
// Get the extension manifest object
$this->manifest = $this->parent->getManifest();
/*
* ---------------------------------------------------------------------------------------------
* Manifest Document Setup Section
* ---------------------------------------------------------------------------------------------
*/
// Set the extensions name
$name = (string) $this->manifest->name;
$name = JFilterInput::getInstance()->clean($name, 'string');
$element = str_replace('.xml', '', basename($this->parent->getPath('manifest')));
$this->set('name', $name);
$this->set('element', $element);
// We don't want to compromise this instance!
$installer = new JInstaller;
$db = $this->parent->getDbo();
$query = $db->getQuery(true)
->select($db->quoteName('extension_id'))
->from($db->quoteName('#__extensions'))
->where($db->quoteName('type') . ' = ' . $db->quote('library'))
->where($db->quoteName('element') . ' = ' . $db->quote($element));
$db->setQuery($query);
$result = $db->loadResult();
if ($result)
{
// Already installed, which would make sense
$installer->uninstall('library', $result);
}
// Now create the new files
return $this->install();
}
/**
* Custom uninstall method
*
* @param string $id The id of the library to uninstall.
*
* @return boolean True on success
*
* @since 3.1
*/
public function uninstall($id)
{
$retval = true;
// First order of business will be to load the module object table from the database.
// This should give us the necessary information to proceed.
$row = JTable::getInstance('extension');
if (!$row->load((int) $id) || !strlen($row->element))
{
JLog::add(JText::_('ERRORUNKOWNEXTENSION'), JLog::WARNING, 'jerror');
return false;
}
// Is the library we are trying to uninstall a core one?
// Because that is not a good idea...
if ($row->protected)
{
JLog::add(JText::_('JLIB_INSTALLER_ERROR_LIB_UNINSTALL_WARNCORELIBRARY'), JLog::WARNING, 'jerror');
return false;
}
$manifestFile = JPATH_MANIFESTS . '/libraries/' . $row->element . '.xml';
// Because libraries may not have their own folders we cannot use the standard method of finding an installation manifest
if (file_exists($manifestFile))
{
$manifest = new JInstallerManifestLibrary($manifestFile);
// Set the library root path
$this->parent->setPath('extension_root', JPATH_PLATFORM . '/' . $manifest->libraryname);
$xml = simplexml_load_file($manifestFile);
// If we cannot load the XML file return null
if (!$xml)
{
JLog::add(JText::_('JLIB_INSTALLER_ERROR_LIB_UNINSTALL_LOAD_MANIFEST'), JLog::WARNING, 'jerror');
return false;
}
// Check for a valid XML root tag.
if ($xml->getName() != 'extension')
{
JLog::add(JText::_('JLIB_INSTALLER_ERROR_LIB_UNINSTALL_INVALID_MANIFEST'), JLog::WARNING, 'jerror');
return false;
}
$this->parent->removeFiles($xml->files, -1);
JFile::delete($manifestFile);
}
else
{
// Remove this row entry since its invalid
$row->delete($row->extension_id);
unset($row);
JLog::add(JText::_('JLIB_INSTALLER_ERROR_LIB_UNINSTALL_INVALID_NOTFOUND_MANIFEST'), JLog::WARNING, 'jerror');
return false;
}
// TODO: Change this so it walked up the path backwards so we clobber multiple empties
// If the folder is empty, let's delete it
if (JFolder::exists($this->parent->getPath('extension_root')))
{
if (is_dir($this->parent->getPath('extension_root')))
{
$files = JFolder::files($this->parent->getPath('extension_root'));
if (!count($files))
{
JFolder::delete($this->parent->getPath('extension_root'));
}
}
}
$this->parent->removeFiles($xml->media);
$this->parent->removeFiles($xml->languages);
$row->delete($row->extension_id);
unset($row);
return $retval;
}
/**
* Custom discover method
*
* @return array JExtension list of extensions available
*
* @since 3.1
*/
public function discover()
{
$results = array();
$file_list = JFolder::files(JPATH_MANIFESTS . '/libraries', '\.xml$');
foreach ($file_list as $file)
{
$manifest_details = JInstaller::parseXMLInstallFile(JPATH_MANIFESTS . '/libraries/' . $file);
$file = JFile::stripExt($file);
$extension = JTable::getInstance('extension');
$extension->set('type', 'library');
$extension->set('client_id', 0);
$extension->set('element', $file);
$extension->set('folder', '');
$extension->set('name', $file);
$extension->set('state', -1);
$extension->set('manifest_cache', json_encode($manifest_details));
$extension->set('params', '{}');
$results[] = $extension;
}
return $results;
}
/**
* Custom discover_install method
*
* @return boolean True on success
*
* @since 3.1
*/
public function discover_install()
{
/* Libraries are a strange beast; they are actually references to files
* There are two parts to a library which are disjunct in their locations
* 1) The manifest file (stored in /JPATH_MANIFESTS/libraries)
* 2) The actual files (stored in /JPATH_PLATFORM/libraryname)
* Thus installation of a library is the process of dumping files
* in two different places. As such it is impossible to perform
* any operation beyond mere registration of a library under the presumption
* that the files exist in the appropriate location so that come uninstall
* time they can be adequately removed.
*/
$manifestPath = JPATH_MANIFESTS . '/libraries/' . $this->parent->extension->element . '.xml';
$this->parent->manifest = $this->parent->isManifest($manifestPath);
$this->parent->setPath('manifest', $manifestPath);
$manifest_details = JInstaller::parseXMLInstallFile($this->parent->getPath('manifest'));
$this->parent->extension->manifest_cache = json_encode($manifest_details);
$this->parent->extension->state = 0;
$this->parent->extension->name = $manifest_details['name'];
$this->parent->extension->enabled = 1;
$this->parent->extension->params = $this->parent->getParams();
if ($this->parent->extension->store())
{
return true;
}
else
{
JLog::add(JText::_('JLIB_INSTALLER_ERROR_LIB_DISCOVER_STORE_DETAILS'), JLog::WARNING, 'jerror');
return false;
}
}
/**
* Refreshes the extension table cache
*
* @return boolean Result of operation, true if updated, false on failure
*
* @since 3.1
*/
public function refreshManifestCache()
{
// Need to find to find where the XML file is since we don't store this normally
$manifestPath = JPATH_MANIFESTS . '/libraries/' . $this->parent->extension->element . '.xml';
$this->parent->manifest = $this->parent->isManifest($manifestPath);
$this->parent->setPath('manifest', $manifestPath);
$manifest_details = JInstaller::parseXMLInstallFile($this->parent->getPath('manifest'));
$this->parent->extension->manifest_cache = json_encode($manifest_details);
$this->parent->extension->name = $manifest_details['name'];
try
{
return $this->parent->extension->store();
}
catch (RuntimeException $e)
{
JLog::add(JText::_('JLIB_INSTALLER_ERROR_LIB_REFRESH_MANIFEST_CACHE'), JLog::WARNING, 'jerror');
return false;
}
}
}
/**
* Deprecated class placeholder. You should use JInstallerAdapterLibrary instead.
*
* @package Joomla.Libraries
* @subpackage Installer
* @since 3.1
* @deprecated 4.0
* @codeCoverageIgnore
*/
class JInstallerLibrary extends JInstallerAdapterLibrary
{
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,631 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage Installer
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
jimport('joomla.base.adapterinstance');
/**
* Package installer
*
* @package Joomla.Libraries
* @subpackage Installer
* @since 3.1
*/
class JInstallerAdapterPackage extends JAdapterInstance
{
/**
* Method of system
*
* @var string
*
* @since 3.1
*/
protected $route = 'install';
/**
* Load language from a path
*
* @param string $path The path of the language.
*
* @return void
*
* @since 3.1
*/
public function loadLanguage($path)
{
$this->manifest = $this->parent->getManifest();
$extension = 'pkg_' . strtolower(JFilterInput::getInstance()->clean((string) $this->manifest->packagename, 'cmd'));
$lang = JFactory::getLanguage();
$source = $path;
$lang->load($extension . '.sys', $source, null, false, false)
|| $lang->load($extension . '.sys', JPATH_SITE, null, false, false)
|| $lang->load($extension . '.sys', $source, $lang->getDefault(), false, false)
|| $lang->load($extension . '.sys', JPATH_SITE, $lang->getDefault(), false, false);
}
/**
* Custom install method
*
* @return int The extension id
*
* @since 3.1
*/
public function install()
{
// Get the extension manifest object
$this->manifest = $this->parent->getManifest();
/*
* ---------------------------------------------------------------------------------------------
* Manifest Document Setup Section
* ---------------------------------------------------------------------------------------------
*/
// Set the extensions name
$filter = JFilterInput::getInstance();
$name = (string) $this->manifest->packagename;
$name = $filter->clean($name, 'cmd');
$this->set('name', $name);
$element = 'pkg_' . $filter->clean($this->manifest->packagename, 'cmd');
$this->set('element', $element);
// Get the component description
$description = (string) $this->manifest->description;
if ($description)
{
$this->parent->set('message', JText::_($description));
}
else
{
$this->parent->set('message', '');
}
// Set the installation path
$files = $this->manifest->files;
$group = (string) $this->manifest->packagename;
if (!empty($group))
{
$this->parent->setPath('extension_root', JPATH_MANIFESTS . '/packages/' . implode(DIRECTORY_SEPARATOR, explode('/', $group)));
}
else
{
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_PACK_INSTALL_NO_PACK', JText::_('JLIB_INSTALLER_' . strtoupper($this->route))));
return false;
}
/*
* If the package manifest already exists, then we will assume that the package is already
* installed.
*/
if (file_exists(JPATH_MANIFESTS . '/packages/' . basename($this->parent->getPath('manifest'))))
{
// Look for an update function or update tag
$updateElement = $this->manifest->update;
// If $this->upgrade has already been set, or an update property exists in the manifest, update the extensions
if ($this->parent->isUpgrade() || $updateElement)
{
// Use the update route for all packaged extensions
$this->route = 'update';
}
}
/**
* ---------------------------------------------------------------------------------------------
* Installer Trigger Loading
* ---------------------------------------------------------------------------------------------
*/
// If there is an manifest class file, lets load it; we'll copy it later (don't have dest yet)
$this->scriptElement = $this->manifest->scriptfile;
$manifestScript = (string) $this->manifest->scriptfile;
if ($manifestScript)
{
$manifestScriptFile = $this->parent->getPath('source') . '/' . $manifestScript;
if (is_file($manifestScriptFile))
{
// Load the file
include_once $manifestScriptFile;
}
// Set the class name
$classname = $element . 'InstallerScript';
if (class_exists($classname))
{
// Create a new instance
$this->parent->manifestClass = new $classname($this);
// And set this so we can copy it later
$this->set('manifest_script', $manifestScript);
}
}
// Run preflight if possible (since we know we're not an update)
ob_start();
ob_implicit_flush(false);
if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'preflight'))
{
if ($this->parent->manifestClass->preflight($this->route, $this) === false)
{
// Preflight failed, rollback changes
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_PACKAGE_INSTALL_CUSTOM_INSTALL_FAILURE'));
return false;
}
}
// Create msg object; first use here
$msg = ob_get_contents();
ob_end_clean();
/*
* ---------------------------------------------------------------------------------------------
* Filesystem Processing Section
* ---------------------------------------------------------------------------------------------
*/
if ($folder = $files->attributes()->folder)
{
$source = $this->parent->getPath('source') . '/' . $folder;
}
else
{
$source = $this->parent->getPath('source');
}
// Install all necessary files
if (count($this->manifest->files->children()))
{
$i = 0;
foreach ($this->manifest->files->children() as $child)
{
$file = $source . '/' . $child;
if (is_dir($file))
{
// If it's actually a directory then fill it up
$package = array();
$package['dir'] = $file;
$package['type'] = JInstallerHelper::detectType($file);
}
else
{
// If it's an archive
$package = JInstallerHelper::unpack($file);
}
$tmpInstaller = new JInstaller;
$installResult = $tmpInstaller->{$this->route}($package['dir']);
if (!$installResult)
{
$this->parent->abort(
JText::sprintf(
'JLIB_INSTALLER_ABORT_PACK_INSTALL_ERROR_EXTENSION', JText::_('JLIB_INSTALLER_' . strtoupper($this->route)),
basename($file)
)
);
return false;
}
else
{
$results[$i] = array(
'name' => $tmpInstaller->manifest->name,
'result' => $installResult
);
}
$i++;
}
}
else
{
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_PACK_INSTALL_NO_FILES', JText::_('JLIB_INSTALLER_' . strtoupper($this->route))));
return false;
}
// Parse optional tags
$this->parent->parseLanguages($this->manifest->languages);
/*
* ---------------------------------------------------------------------------------------------
* Extension Registration
* ---------------------------------------------------------------------------------------------
*/
$row = JTable::getInstance('extension');
$eid = $row->find(array('element' => strtolower($this->get('element')), 'type' => 'package'));
if ($eid)
{
$row->load($eid);
}
else
{
$row->name = $this->get('name');
$row->type = 'package';
$row->element = $this->get('element');
// There is no folder for modules
$row->folder = '';
$row->enabled = 1;
$row->protected = 0;
$row->access = 1;
$row->client_id = 0;
// Custom data
$row->custom_data = '';
$row->params = $this->parent->getParams();
}
// Update the manifest cache for the entry
$row->manifest_cache = $this->parent->generateManifestCache();
if (!$row->store())
{
// Install failed, roll back changes
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_PACK_INSTALL_ROLLBACK', $row->getError()));
return false;
}
/*
* ---------------------------------------------------------------------------------------------
* Finalization and Cleanup Section
* ---------------------------------------------------------------------------------------------
*/
// Run the custom method based on the route
ob_start();
ob_implicit_flush(false);
if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, $this->route))
{
if ($this->parent->manifestClass->{$this->route}($this) === false)
{
// Install failed, rollback changes
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_FILE_INSTALL_CUSTOM_INSTALL_FAILURE'));
return false;
}
}
// Append messages
$msg .= ob_get_contents();
ob_end_clean();
// Lastly, we will copy the manifest file to its appropriate place.
$manifest = array();
$manifest['src'] = $this->parent->getPath('manifest');
$manifest['dest'] = JPATH_MANIFESTS . '/packages/' . basename($this->parent->getPath('manifest'));
if (!$this->parent->copyFiles(array($manifest), true))
{
// Install failed, rollback changes
$this->parent->abort(
JText::sprintf('JLIB_INSTALLER_ABORT_PACK_INSTALL_COPY_SETUP', JText::_('JLIB_INSTALLER_ABORT_PACK_INSTALL_NO_FILES'))
);
return false;
}
// If there is a manifest script, let's copy it.
if ($this->get('manifest_script'))
{
// First, we have to create a folder for the script if one isn't present
if (!file_exists($this->parent->getPath('extension_root')))
{
JFolder::create($this->parent->getPath('extension_root'));
}
$path['src'] = $this->parent->getPath('source') . '/' . $this->get('manifest_script');
$path['dest'] = $this->parent->getPath('extension_root') . '/' . $this->get('manifest_script');
if (!file_exists($path['dest']) || $this->parent->isOverwrite())
{
if (!$this->parent->copyFiles(array($path)))
{
// Install failed, rollback changes
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_PACKAGE_INSTALL_MANIFEST'));
return false;
}
}
}
// And now we run the postflight
ob_start();
ob_implicit_flush(false);
if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'postflight'))
{
$this->parent->manifestClass->postflight($this->route, $this, $results);
}
// Append messages
$msg .= ob_get_contents();
ob_end_clean();
if ($msg != '')
{
$this->parent->set('extension_message', $msg);
}
return $row->extension_id;
}
/**
* Updates a package
*
* The only difference between an update and a full install
* is how we handle the database
*
* @return void
*
* @since 3.1
*/
public function update()
{
$this->route = 'update';
$this->install();
}
/**
* Custom uninstall method
*
* @param integer $id The id of the package to uninstall.
*
* @return boolean True on success
*
* @since 3.1
*/
public function uninstall($id)
{
$row = null;
$retval = true;
$row = JTable::getInstance('extension');
$row->load($id);
if ($row->protected)
{
JLog::add(JText::_('JLIB_INSTALLER_ERROR_PACK_UNINSTALL_WARNCOREPACK'), JLog::WARNING, 'jerror');
return false;
}
$manifestFile = JPATH_MANIFESTS . '/packages/' . $row->get('element') . '.xml';
$manifest = new JInstallerManifestPackage($manifestFile);
// Set the package root path
$this->parent->setPath('extension_root', JPATH_MANIFESTS . '/packages/' . $manifest->packagename);
// Because packages may not have their own folders we cannot use the standard method of finding an installation manifest
if (!file_exists($manifestFile))
{
// TODO: Fail?
JLog::add(JText::_('JLIB_INSTALLER_ERROR_PACK_UNINSTALL_MISSINGMANIFEST'), JLog::WARNING, 'jerror');
return false;
}
$xml = simplexml_load_file($manifestFile);
// If we cannot load the XML file return false
if (!$xml)
{
JLog::add(JText::_('JLIB_INSTALLER_ERROR_PACK_UNINSTALL_LOAD_MANIFEST'), JLog::WARNING, 'jerror');
return false;
}
// Check for a valid XML root tag.
if ($xml->getName() != 'extension')
{
JLog::add(JText::_('JLIB_INSTALLER_ERROR_PACK_UNINSTALL_INVALID_MANIFEST'), JLog::WARNING, 'jerror');
return false;
}
// If there is an manifest class file, let's load it
$this->scriptElement = $manifest->scriptfile;
$manifestScript = (string) $manifest->scriptfile;
if ($manifestScript)
{
$manifestScriptFile = $this->parent->getPath('extension_root') . '/' . $manifestScript;
if (is_file($manifestScriptFile))
{
// Load the file
include_once $manifestScriptFile;
}
// Set the class name
$classname = $row->element . 'InstallerScript';
if (class_exists($classname))
{
// Create a new instance
$this->parent->manifestClass = new $classname($this);
// And set this so we can copy it later
$this->set('manifest_script', $manifestScript);
}
}
ob_start();
ob_implicit_flush(false);
// Run uninstall if possible
if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'uninstall'))
{
$this->parent->manifestClass->uninstall($this);
}
$msg = ob_get_contents();
ob_end_clean();
if ($msg != '')
{
$this->parent->set('extension_message', $msg);
}
$error = false;
foreach ($manifest->filelist as $extension)
{
$tmpInstaller = new JInstaller;
$id = $this->_getExtensionID($extension->type, $extension->id, $extension->client, $extension->group);
$client = JApplicationHelper::getClientInfo($extension->client, true);
if ($id)
{
if (!$tmpInstaller->uninstall($extension->type, $id, $client->id))
{
$error = true;
JLog::add(JText::sprintf('JLIB_INSTALLER_ERROR_PACK_UNINSTALL_NOT_PROPER', basename($extension->filename)), JLog::WARNING, 'jerror');
}
}
else
{
JLog::add(JText::_('JLIB_INSTALLER_ERROR_PACK_UNINSTALL_UNKNOWN_EXTENSION'), JLog::WARNING, 'jerror');
}
}
// Remove any language files
$this->parent->removeFiles($xml->languages);
// Clean up manifest file after we're done if there were no errors
if (!$error)
{
JFile::delete($manifestFile);
$folder = $this->parent->getPath('extension_root');
if (JFolder::exists($folder))
{
JFolder::delete($folder);
}
$row->delete();
}
else
{
JLog::add(JText::_('JLIB_INSTALLER_ERROR_PACK_UNINSTALL_MANIFEST_NOT_REMOVED'), JLog::WARNING, 'jerror');
}
// Return the result up the line
return $retval;
}
/**
* Gets the extension id.
*
* @param string $type The extension type.
* @param string $id The name of the extension (the element field).
* @param integer $client The application id (0: Joomla CMS site; 1: Joomla CMS administrator).
* @param string $group The extension group (mainly for plugins).
*
* @return integer
*
* @since 3.1
*/
protected function _getExtensionID($type, $id, $client, $group)
{
$db = $this->parent->getDbo();
$query = $db->getQuery(true)
->select('extension_id')
->from('#__extensions')
->where('type = ' . $db->quote($type))
->where('element = ' . $db->quote($id));
switch ($type)
{
case 'plugin':
// Plugins have a folder but not a client
$query->where('folder = ' . $db->quote($group));
break;
case 'library':
case 'package':
case 'component':
// Components, packages and libraries don't have a folder or client.
// Included for completeness.
break;
case 'language':
case 'module':
case 'template':
// Languages, modules and templates have a client but not a folder
$client = JApplicationHelper::getClientInfo($client, true);
$query->where('client_id = ' . (int) $client->id);
break;
}
$db->setQuery($query);
$result = $db->loadResult();
// Note: For templates, libraries and packages their unique name is their key.
// This means they come out the same way they came in.
return $result;
}
/**
* Refreshes the extension table cache
*
* @return boolean Result of operation, true if updated, false on failure
*
* @since 3.1
*/
public function refreshManifestCache()
{
// Need to find to find where the XML file is since we don't store this normally
$manifestPath = JPATH_MANIFESTS . '/packages/' . $this->parent->extension->element . '.xml';
$this->parent->manifest = $this->parent->isManifest($manifestPath);
$this->parent->setPath('manifest', $manifestPath);
$manifest_details = JInstaller::parseXMLInstallFile($this->parent->getPath('manifest'));
$this->parent->extension->manifest_cache = json_encode($manifest_details);
$this->parent->extension->name = $manifest_details['name'];
try
{
return $this->parent->extension->store();
}
catch (RuntimeException $e)
{
JLog::add(JText::_('JLIB_INSTALLER_ERROR_PACK_REFRESH_MANIFEST_CACHE'), JLog::WARNING, 'jerror');
return false;
}
}
}
/**
* Deprecated class placeholder. You should use JInstallerAdapterPackage instead.
*
* @package Joomla.Libraries
* @subpackage Installer
* @since 3.1
* @deprecated 4.0
* @codeCoverageIgnore
*/
class JInstallerPackage extends JInstallerAdapterPackage
{
}

View File

@ -0,0 +1,923 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage Installer
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
jimport('joomla.base.adapterinstance');
jimport('joomla.filesystem.folder');
/**
* Plugin installer
*
* @package Joomla.Libraries
* @subpackage Installer
* @since 3.1
*/
class JInstallerAdapterPlugin extends JAdapterInstance
{
/**
* Install function routing
*
* @var string
* @since 3.1
* */
protected $route = 'install';
/**
* The installation manifest XML object
*
* @var
* @since 3.1
* */
protected $manifest = null;
/**
* A path to the PHP file that the scriptfile declaration in
* the manifest refers to.
*
* @var
* @since 3.1
* */
protected $manifest_script = null;
/**
* Name of the extension
*
* @var
* @since 3.1
* */
protected $name = null;
/**
*
*
* @var
* @since 3.1
* */
protected $scriptElement = null;
/**
* @var
* @since 3.1
*/
protected $oldFiles = null;
/**
* Custom loadLanguage method
*
* @param string $path The path where to find language files.
*
* @return void
*
* @since 3.1
*/
public function loadLanguage($path = null)
{
$source = $this->parent->getPath('source');
if (!$source)
{
$this->parent->setPath('source', JPATH_PLUGINS . '/' . $this->parent->extension->folder . '/' . $this->parent->extension->element);
}
$this->manifest = $this->parent->getManifest();
$element = $this->manifest->files;
if ($element)
{
$group = strtolower((string) $this->manifest->attributes()->group);
$name = '';
if (count($element->children()))
{
foreach ($element->children() as $file)
{
if ((string) $file->attributes()->plugin)
{
$name = strtolower((string) $file->attributes()->plugin);
break;
}
}
}
if ($name)
{
$extension = "plg_${group}_${name}";
$lang = JFactory::getLanguage();
$source = $path ? $path : JPATH_PLUGINS . "/$group/$name";
$folder = (string) $element->attributes()->folder;
if ($folder && file_exists("$path/$folder"))
{
$source = "$path/$folder";
}
$lang->load($extension . '.sys', $source, null, false, false)
|| $lang->load($extension . '.sys', JPATH_ADMINISTRATOR, null, false, false)
|| $lang->load($extension . '.sys', $source, $lang->getDefault(), false, false)
|| $lang->load($extension . '.sys', JPATH_ADMINISTRATOR, $lang->getDefault(), false, false);
}
}
}
/**
* Custom install method
*
* @return boolean True on success
*
* @since 3.1
*/
public function install()
{
// Get a database connector object
$db = $this->parent->getDbo();
// Get the extension manifest object
$this->manifest = $this->parent->getManifest();
$xml = $this->manifest;
/*
* ---------------------------------------------------------------------------------------------
* Manifest Document Setup Section
* ---------------------------------------------------------------------------------------------
*/
// Set the extension name
$name = (string) $xml->name;
$name = JFilterInput::getInstance()->clean($name, 'string');
$this->set('name', $name);
// Get the plugin description
$description = (string) $xml->description;
if ($description)
{
$this->parent->set('message', JText::_($description));
}
else
{
$this->parent->set('message', '');
}
/*
* Backward Compatibility
* @todo Deprecate in future version
*/
$type = (string) $xml->attributes()->type;
// Set the installation path
if (count($xml->files->children()))
{
foreach ($xml->files->children() as $file)
{
if ((string) $file->attributes()->$type)
{
$element = (string) $file->attributes()->$type;
break;
}
}
}
$group = (string) $xml->attributes()->group;
if (!empty($element) && !empty($group))
{
$this->parent->setPath('extension_root', JPATH_PLUGINS . '/' . $group . '/' . $element);
}
else
{
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_PLG_INSTALL_NO_FILE', JText::_('JLIB_INSTALLER_' . $this->route)));
return false;
}
// Check if we should enable overwrite settings
// Check to see if a plugin by the same name is already installed.
$query = $db->getQuery(true)
->select($db->quoteName('extension_id'))
->from($db->quoteName('#__extensions'))
->where($db->quoteName('folder') . ' = ' . $db->quote($group))
->where($db->quoteName('element') . ' = ' . $db->quote($element));
$db->setQuery($query);
try
{
$db->execute();
}
catch (RuntimeException $e)
{
// Install failed, roll back changes
$this->parent
->abort(JText::sprintf('JLIB_INSTALLER_ABORT_PLG_INSTALL_ROLLBACK', JText::_('JLIB_INSTALLER_' . $this->route), $db->stderr(true)));
return false;
}
$id = $db->loadResult();
// If it's on the fs...
if (file_exists($this->parent->getPath('extension_root')) && (!$this->parent->isOverwrite() || $this->parent->isUpgrade()))
{
$updateElement = $xml->update;
// Upgrade manually set or update function available or update tag detected
if ($this->parent->isUpgrade() || ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'update'))
|| $updateElement)
{
// Force this one
$this->parent->setOverwrite(true);
$this->parent->setUpgrade(true);
if ($id)
{
// If there is a matching extension mark this as an update; semantics really
$this->route = 'update';
}
}
elseif (!$this->parent->isOverwrite())
{
// Overwrite is set
// We didn't have overwrite set, find an update function or find an update tag so lets call it safe
$this->parent
->abort(
JText::sprintf(
'JLIB_INSTALLER_ABORT_PLG_INSTALL_DIRECTORY', JText::_('JLIB_INSTALLER_' . $this->route),
$this->parent->getPath('extension_root')
)
);
return false;
}
}
/*
* ---------------------------------------------------------------------------------------------
* Installer Trigger Loading
* ---------------------------------------------------------------------------------------------
*/
// If there is an manifest class file, let's load it; we'll copy it later (don't have destination yet).
if ((string) $xml->scriptfile)
{
$manifestScript = (string) $xml->scriptfile;
$manifestScriptFile = $this->parent->getPath('source') . '/' . $manifestScript;
if (is_file($manifestScriptFile))
{
// Load the file
include_once $manifestScriptFile;
}
// If a dash is present in the group name, remove it
$groupClass = str_replace('-', '', $group);
// Set the class name
$classname = 'plg' . $groupClass . $element . 'InstallerScript';
if (class_exists($classname))
{
// Create a new instance
$this->parent->manifestClass = new $classname($this);
// And set this so we can copy it later
$this->set('manifest_script', $manifestScript);
}
}
// Run preflight if possible (since we know we're not an update)
ob_start();
ob_implicit_flush(false);
if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'preflight'))
{
if ($this->parent->manifestClass->preflight($this->route, $this) === false)
{
// Install failed, rollback changes
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_PLG_INSTALL_CUSTOM_INSTALL_FAILURE'));
return false;
}
}
// Create msg object; first use here
$msg = ob_get_contents();
ob_end_clean();
/*
* ---------------------------------------------------------------------------------------------
* Filesystem Processing Section
* ---------------------------------------------------------------------------------------------
*/
// If the plugin directory does not exist, lets create it
$created = false;
if (!file_exists($this->parent->getPath('extension_root')))
{
if (!$created = JFolder::create($this->parent->getPath('extension_root')))
{
$this->parent
->abort(
JText::sprintf(
'JLIB_INSTALLER_ABORT_PLG_INSTALL_CREATE_DIRECTORY', JText::_('JLIB_INSTALLER_' . $this->route),
$this->parent->getPath('extension_root')
)
);
return false;
}
}
// If we're updating at this point when there is always going to be an extension_root find the old XML files
if ($this->route == 'update')
{
// Hunt for the original XML file
$old_manifest = null;
// Create a new installer because findManifest sets stuff; side effects!
$tmpInstaller = new JInstaller;
// Look in the extension root
$tmpInstaller->setPath('source', $this->parent->getPath('extension_root'));
if ($tmpInstaller->findManifest())
{
$old_manifest = $tmpInstaller->getManifest();
$this->oldFiles = $old_manifest->files;
}
}
/*
* If we created the plugin directory and will want to remove it if we
* have to roll back the installation, let's add it to the installation
* step stack
*/
if ($created)
{
$this->parent->pushStep(array('type' => 'folder', 'path' => $this->parent->getPath('extension_root')));
}
// Copy all necessary files
if ($this->parent->parseFiles($xml->files, -1, $this->oldFiles) === false)
{
// Install failed, roll back changes
$this->parent->abort();
return false;
}
// Parse optional tags -- media and language files for plugins go in admin app
$this->parent->parseMedia($xml->media, 1);
$this->parent->parseLanguages($xml->languages, 1);
// If there is a manifest script, lets copy it.
if ($this->get('manifest_script'))
{
$path['src'] = $this->parent->getPath('source') . '/' . $this->get('manifest_script');
$path['dest'] = $this->parent->getPath('extension_root') . '/' . $this->get('manifest_script');
if (!file_exists($path['dest']))
{
if (!$this->parent->copyFiles(array($path)))
{
// Install failed, rollback changes
$this->parent
->abort(JText::sprintf('JLIB_INSTALLER_ABORT_PLG_INSTALL_MANIFEST', JText::_('JLIB_INSTALLER_' . $this->route)));
return false;
}
}
}
/*
* ---------------------------------------------------------------------------------------------
* Database Processing Section
* ---------------------------------------------------------------------------------------------
*/
$row = JTable::getInstance('extension');
// Was there a plugin with the same name already installed?
if ($id)
{
if (!$this->parent->isOverwrite())
{
// Install failed, roll back changes
$this->parent
->abort(
JText::sprintf(
'JLIB_INSTALLER_ABORT_PLG_INSTALL_ALLREADY_EXISTS', JText::_('JLIB_INSTALLER_' . $this->route),
$this->get('name')
)
);
return false;
}
$row->load($id);
$row->name = $this->get('name');
$row->manifest_cache = $this->parent->generateManifestCache();
// Update the manifest cache and name
$row->store();
}
else
{
// Store in the extensions table (1.6)
$row->name = $this->get('name');
$row->type = 'plugin';
$row->ordering = 0;
$row->element = $element;
$row->folder = $group;
$row->enabled = 0;
$row->protected = 0;
$row->access = 1;
$row->client_id = 0;
$row->params = $this->parent->getParams();
// Custom data
$row->custom_data = '';
// System data
$row->system_data = '';
$row->manifest_cache = $this->parent->generateManifestCache();
// Editor plugins are published by default
if ($group == 'editors')
{
$row->enabled = 1;
}
if (!$row->store())
{
// Install failed, roll back changes
$this->parent
->abort(
JText::sprintf('JLIB_INSTALLER_ABORT_PLG_INSTALL_ROLLBACK', JText::_('JLIB_INSTALLER_' . $this->route), $db->stderr(true))
);
return false;
}
// Since we have created a plugin item, we add it to the installation step stack
// so that if we have to rollback the changes we can undo it.
$this->parent->pushStep(array('type' => 'extension', 'id' => $row->extension_id));
$id = $row->extension_id;
}
// Let's run the queries for the plugin
if (strtolower($this->route) == 'install')
{
$result = $this->parent->parseSQLFiles($this->manifest->install->sql);
if ($result === false)
{
// Install failed, rollback changes
$this->parent
->abort(
JText::sprintf('JLIB_INSTALLER_ABORT_PLG_INSTALL_SQL_ERROR', JText::_('JLIB_INSTALLER_' . $this->route), $db->stderr(true))
);
return false;
}
// Set the schema version to be the latest update version
if ($this->manifest->update)
{
$this->parent->setSchemaVersion($this->manifest->update->schemas, $row->extension_id);
}
}
elseif (strtolower($this->route) == 'update')
{
if ($this->manifest->update)
{
$result = $this->parent->parseSchemaUpdates($this->manifest->update->schemas, $row->extension_id);
if ($result === false)
{
// Install failed, rollback changes
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_PLG_UPDATE_SQL_ERROR', $db->stderr(true)));
return false;
}
}
}
// Run the custom method based on the route
ob_start();
ob_implicit_flush(false);
if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, $this->route))
{
if ($this->parent->manifestClass->{$this->route}($this) === false)
{
// Install failed, rollback changes
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_PLG_INSTALL_CUSTOM_INSTALL_FAILURE'));
return false;
}
}
// Append messages
$msg .= ob_get_contents();
ob_end_clean();
/**
* ---------------------------------------------------------------------------------------------
* Finalization and Cleanup Section
* ---------------------------------------------------------------------------------------------
*/
// Lastly, we will copy the manifest file to its appropriate place.
if (!$this->parent->copyManifest(-1))
{
// Install failed, rollback changes
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_PLG_INSTALL_COPY_SETUP', JText::_('JLIB_INSTALLER_' . $this->route)));
return false;
}
// And now we run the postflight
ob_start();
ob_implicit_flush(false);
if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'postflight'))
{
$this->parent->manifestClass->postflight($this->route, $this);
}
// Append messages
$msg .= ob_get_contents();
ob_end_clean();
if ($msg != '')
{
$this->parent->set('extension_message', $msg);
}
return $id;
}
/**
* Custom update method
*
* @return boolean True on success
*
* @since 3.1
*/
public function update()
{
// Set the overwrite setting
$this->parent->setOverwrite(true);
$this->parent->setUpgrade(true);
// Set the route for the install
$this->route = 'update';
// Go to install which handles updates properly
return $this->install();
}
/**
* Custom uninstall method
*
* @param integer $id The id of the plugin to uninstall
*
* @return boolean True on success
*
* @since 3.1
*/
public function uninstall($id)
{
$this->route = 'uninstall';
$row = null;
$retval = true;
$db = $this->parent->getDbo();
// First order of business will be to load the plugin object table from the database.
// This should give us the necessary information to proceed.
$row = JTable::getInstance('extension');
if (!$row->load((int) $id))
{
JLog::add(JText::_('JLIB_INSTALLER_ERROR_PLG_UNINSTALL_ERRORUNKOWNEXTENSION'), JLog::WARNING, 'jerror');
return false;
}
// Is the plugin we are trying to uninstall a core one?
// Because that is not a good idea...
if ($row->protected)
{
JLog::add(JText::sprintf('JLIB_INSTALLER_ERROR_PLG_UNINSTALL_WARNCOREPLUGIN', $row->name), JLog::WARNING, 'jerror');
return false;
}
// Get the plugin folder so we can properly build the plugin path
if (trim($row->folder) == '')
{
JLog::add(JText::_('JLIB_INSTALLER_ERROR_PLG_UNINSTALL_FOLDER_FIELD_EMPTY'), JLog::WARNING, 'jerror');
return false;
}
// Set the plugin root path
$this->parent->setPath('extension_root', JPATH_PLUGINS . '/' . $row->folder . '/' . $row->element);
$this->parent->setPath('source', $this->parent->getPath('extension_root'));
$this->parent->findManifest();
$this->manifest = $this->parent->getManifest();
// Attempt to load the language file; might have uninstall strings
$this->parent->setPath('source', JPATH_PLUGINS . '/' . $row->folder . '/' . $row->element);
$this->loadLanguage(JPATH_PLUGINS . '/' . $row->folder . '/' . $row->element);
/**
* ---------------------------------------------------------------------------------------------
* Installer Trigger Loading
* ---------------------------------------------------------------------------------------------
*/
// If there is an manifest class file, let's load it; we'll copy it later (don't have dest yet)
$manifestScript = (string) $this->manifest->scriptfile;
if ($manifestScript)
{
$manifestScriptFile = $this->parent->getPath('source') . '/' . $manifestScript;
if (is_file($manifestScriptFile))
{
// Load the file
include_once $manifestScriptFile;
}
// If a dash is present in the folder, remove it
$folderClass = str_replace('-', '', $row->folder);
// Set the class name
$classname = 'plg' . $folderClass . $row->element . 'InstallerScript';
if (class_exists($classname))
{
// Create a new instance
$this->parent->manifestClass = new $classname($this);
// And set this so we can copy it later
$this->set('manifest_script', $manifestScript);
}
}
// Run preflight if possible (since we know we're not an update)
ob_start();
ob_implicit_flush(false);
if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'preflight'))
{
if ($this->parent->manifestClass->preflight($this->route, $this) === false)
{
// Preflight failed, rollback changes
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_PLG_INSTALL_CUSTOM_INSTALL_FAILURE'));
return false;
}
}
// Create the $msg object and append messages from preflight
$msg = ob_get_contents();
ob_end_clean();
// Let's run the queries for the plugin
$utfresult = $this->parent->parseSQLFiles($this->manifest->uninstall->sql);
if ($utfresult === false)
{
// Install failed, rollback changes
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_PLG_UNINSTALL_SQL_ERROR', $db->stderr(true)));
return false;
}
// Run the custom uninstall method if possible
ob_start();
ob_implicit_flush(false);
if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'uninstall'))
{
$this->parent->manifestClass->uninstall($this);
}
// Append messages
$msg .= ob_get_contents();
ob_end_clean();
// Remove the plugin files
$this->parent->removeFiles($this->manifest->files, -1);
// Remove all media and languages as well
$this->parent->removeFiles($this->manifest->media);
$this->parent->removeFiles($this->manifest->languages, 1);
// Remove the schema version
$query = $db->getQuery(true)
->delete('#__schemas')
->where('extension_id = ' . $row->extension_id);
$db->setQuery($query);
$db->execute();
// Now we will no longer need the plugin object, so let's delete it
$row->delete($row->extension_id);
unset($row);
// Remove the plugin's folder
JFolder::delete($this->parent->getPath('extension_root'));
if ($msg != '')
{
$this->parent->set('extension_message', $msg);
}
return $retval;
}
/**
* Custom discover method
*
* @return array JExtension) list of extensions available
*
* @since 3.1
*/
public function discover()
{
$results = array();
$folder_list = JFolder::folders(JPATH_SITE . '/plugins');
foreach ($folder_list as $folder)
{
$file_list = JFolder::files(JPATH_SITE . '/plugins/' . $folder, '\.xml$');
foreach ($file_list as $file)
{
$manifest_details = JInstaller::parseXMLInstallFile(JPATH_SITE . '/plugins/' . $folder . '/' . $file);
$file = JFile::stripExt($file);
// Ignore example plugins
if ($file == 'example')
{
continue;
}
$extension = JTable::getInstance('extension');
$extension->set('type', 'plugin');
$extension->set('client_id', 0);
$extension->set('element', $file);
$extension->set('folder', $folder);
$extension->set('name', $file);
$extension->set('state', -1);
$extension->set('manifest_cache', json_encode($manifest_details));
$extension->set('params', '{}');
$results[] = $extension;
}
$folder_list = JFolder::folders(JPATH_SITE . '/plugins/' . $folder);
foreach ($folder_list as $plugin_folder)
{
$file_list = JFolder::files(JPATH_SITE . '/plugins/' . $folder . '/' . $plugin_folder, '\.xml$');
foreach ($file_list as $file)
{
$manifest_details = JInstaller::parseXMLInstallFile(
JPATH_SITE . '/plugins/' . $folder . '/' . $plugin_folder . '/' . $file
);
$file = JFile::stripExt($file);
if ($file == 'example')
{
continue;
}
// Ignore example plugins
$extension = JTable::getInstance('extension');
$extension->set('type', 'plugin');
$extension->set('client_id', 0);
$extension->set('element', $file);
$extension->set('folder', $folder);
$extension->set('name', $file);
$extension->set('state', -1);
$extension->set('manifest_cache', json_encode($manifest_details));
$extension->set('params', '{}');
$results[] = $extension;
}
}
}
return $results;
}
/**
* Custom discover_install method.
*
* @return mixed
*
* @since 3.1
*/
public function discover_install()
{
/*
* Plugins use the extensions table as their primary store
* Similar to modules and templates, rather easy
* If it's not in the extensions table we just add it
*/
$client = JApplicationHelper::getClientInfo($this->parent->extension->client_id);
if (is_dir($client->path . '/plugins/' . $this->parent->extension->folder . '/' . $this->parent->extension->element))
{
$manifestPath = $client->path . '/plugins/' . $this->parent->extension->folder . '/' . $this->parent->extension->element . '/'
. $this->parent->extension->element . '.xml';
}
else
{
$manifestPath = $client->path . '/plugins/' . $this->parent->extension->folder . '/' . $this->parent->extension->element . '.xml';
}
$this->parent->manifest = $this->parent->isManifest($manifestPath);
$description = (string) $this->parent->manifest->description;
if ($description)
{
$this->parent->set('message', JText::_($description));
}
else
{
$this->parent->set('message', '');
}
$this->parent->setPath('manifest', $manifestPath);
$manifest_details = JInstaller::parseXMLInstallFile($manifestPath);
$this->parent->extension->manifest_cache = json_encode($manifest_details);
$this->parent->extension->state = 0;
$this->parent->extension->name = $manifest_details['name'];
$this->parent->extension->enabled = ('editors' == $this->parent->extension->folder) ? 1 : 0;
$this->parent->extension->params = $this->parent->getParams();
if ($this->parent->extension->store())
{
return $this->parent->extension->get('extension_id');
}
else
{
JLog::add(JText::_('JLIB_INSTALLER_ERROR_PLG_DISCOVER_STORE_DETAILS'), JLog::WARNING, 'jerror');
return false;
}
}
/**
* Refreshes the extension table cache.
*
* @return boolean Result of operation, true if updated, false on failure.
*
* @since 3.1
*/
public function refreshManifestCache()
{
/*
* Plugins use the extensions table as their primary store
* Similar to modules and templates, rather easy
* If it's not in the extensions table we just add it
*/
$client = JApplicationHelper::getClientInfo($this->parent->extension->client_id);
$manifestPath = $client->path . '/plugins/' . $this->parent->extension->folder . '/' . $this->parent->extension->element . '/'
. $this->parent->extension->element . '.xml';
$this->parent->manifest = $this->parent->isManifest($manifestPath);
$this->parent->setPath('manifest', $manifestPath);
$manifest_details = JInstaller::parseXMLInstallFile($this->parent->getPath('manifest'));
$this->parent->extension->manifest_cache = json_encode($manifest_details);
$this->parent->extension->name = $manifest_details['name'];
if ($this->parent->extension->store())
{
return true;
}
else
{
JLog::add(JText::_('JLIB_INSTALLER_ERROR_PLG_REFRESH_MANIFEST_CACHE'), JLog::WARNING, 'jerror');
return false;
}
}
}
/**
* Deprecated class placeholder. You should use JInstallerAdapterPlugin instead.
*
* @package Joomla.Libraries
* @subpackage Installer
* @since 3.1
* @deprecated 4.0
* @codeCoverageIgnore
*/
class JInstallerPlugin extends JInstallerAdapterPlugin
{
}

View File

@ -0,0 +1,661 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage Installer
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
jimport('joomla.base.adapterinstance');
jimport('joomla.filesystem.folder');
/**
* Template installer
*
* @package Joomla.Libraries
* @subpackage Installer
* @since 3.1
*/
class JInstallerAdapterTemplate extends JAdapterInstance
{
/**
* Copy of the XML manifest file
*
* @var string
* @since 3.1
*/
protected $manifest = null;
/**
* Name of the extension
*
* @var string
* @since 3.1
* */
protected $name = null;
/**
* The unique identifier for the extension (e.g. mod_login)
*
* @var string
* @since 3.1
* */
protected $element = null;
/**
* Method of system
*
* @var string
*
* @since 3.1
*/
protected $route = 'install';
/**
* Custom loadLanguage method
*
* @param string $path The path where to find language files.
*
* @return JInstallerTemplate
*
* @since 3.1
*/
public function loadLanguage($path = null)
{
$source = $this->parent->getPath('source');
if (!$source)
{
$this->parent
->setPath(
'source',
($this->parent->extension->client_id ? JPATH_ADMINISTRATOR : JPATH_SITE) . '/templates/' . $this->parent->extension->element
);
}
$this->manifest = $this->parent->getManifest();
$name = strtolower(JFilterInput::getInstance()->clean((string) $this->manifest->name, 'cmd'));
$client = (string) $this->manifest->attributes()->client;
// Load administrator language if not set.
if (!$client)
{
$client = 'ADMINISTRATOR';
}
$extension = "tpl_$name";
$lang = JFactory::getLanguage();
$source = $path ? $path : ($this->parent->extension->client_id ? JPATH_ADMINISTRATOR : JPATH_SITE) . '/templates/' . $name;
$lang->load($extension . '.sys', $source, null, false, false)
|| $lang->load($extension . '.sys', constant('JPATH_' . strtoupper($client)), null, false, false)
|| $lang->load($extension . '.sys', $source, $lang->getDefault(), false, false)
|| $lang->load($extension . '.sys', constant('JPATH_' . strtoupper($client)), $lang->getDefault(), false, false);
}
/**
* Custom install method
*
* @return boolean True on success
*
* @since 3.1
*/
public function install()
{
// Get a database connector object
$db = $this->parent->getDbo();
$lang = JFactory::getLanguage();
$xml = $this->parent->getManifest();
// Get the client application target
if ($cname = (string) $xml->attributes()->client)
{
// Attempt to map the client to a base path
$client = JApplicationHelper::getClientInfo($cname, true);
if ($client === false)
{
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_TPL_INSTALL_UNKNOWN_CLIENT', $cname));
return false;
}
$basePath = $client->path;
$clientId = $client->id;
}
else
{
// No client attribute was found so we assume the site as the client
$basePath = JPATH_SITE;
$clientId = 0;
}
// Set the extension's name
$name = JFilterInput::getInstance()->clean((string) $xml->name, 'cmd');
$element = strtolower(str_replace(" ", "_", $name));
$this->set('name', $name);
$this->set('element', $element);
// Check to see if a template by the same name is already installed.
$query = $db->getQuery(true)
->select($db->quoteName('extension_id'))
->from($db->quoteName('#__extensions'))
->where($db->quoteName('type') . ' = ' . $db->quote('template'))
->where($db->quoteName('element') . ' = ' . $db->quote($element));
$db->setQuery($query);
try
{
$id = $db->loadResult();
}
catch (RuntimeException $e)
{
// Install failed, roll back changes
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_TPL_INSTALL_ROLLBACK'), $e->getMessage());
return false;
}
// Set the template root path
$this->parent->setPath('extension_root', $basePath . '/templates/' . $element);
// If it's on the fs...
if (file_exists($this->parent->getPath('extension_root')) && (!$this->parent->isOverwrite() || $this->parent->isUpgrade()))
{
$updateElement = $xml->update;
// Upgrade manually set or update tag detected
if ($this->parent->isUpgrade() || $updateElement)
{
// Force this one
$this->parent->setOverwrite(true);
$this->parent->setUpgrade(true);
if ($id)
{
// If there is a matching extension mark this as an update; semantics really
$this->route = 'update';
}
}
elseif (!$this->parent->isOverwrite())
{
// Overwrite is not set
// If we didn't have overwrite set, find an update function or find an update tag so let's call it safe
$this->parent
->abort(
JText::sprintf(
'JLIB_INSTALLER_ABORT_TPL_INSTALL_ANOTHER_TEMPLATE_USING_DIRECTORY', JText::_('JLIB_INSTALLER_' . $this->route),
$this->parent->getPath('extension_root')
)
);
return false;
}
}
/*
* If the template directory already exists, then we will assume that the template is already
* installed or another template is using that directory.
*/
if (file_exists($this->parent->getPath('extension_root')) && !$this->parent->isOverwrite())
{
JLog::add(
JText::sprintf('JLIB_INSTALLER_ABORT_TPL_INSTALL_ANOTHER_TEMPLATE_USING_DIRECTORY', $this->parent->getPath('extension_root')),
JLog::WARNING, 'jerror'
);
return false;
}
// If the template directory does not exist, let's create it
$created = false;
if (!file_exists($this->parent->getPath('extension_root')))
{
if (!$created = JFolder::create($this->parent->getPath('extension_root')))
{
$this->parent
->abort(JText::sprintf('JLIB_INSTALLER_ABORT_TPL_INSTALL_FAILED_CREATE_DIRECTORY', $this->parent->getPath('extension_root')));
return false;
}
}
// If we created the template directory and will want to remove it if we have to roll back
// the installation, let's add it to the installation step stack
if ($created)
{
$this->parent->pushStep(array('type' => 'folder', 'path' => $this->parent->getPath('extension_root')));
}
// Copy all the necessary files
if ($this->parent->parseFiles($xml->files, -1) === false)
{
// Install failed, rollback changes
$this->parent->abort();
return false;
}
if ($this->parent->parseFiles($xml->images, -1) === false)
{
// Install failed, rollback changes
$this->parent->abort();
return false;
}
if ($this->parent->parseFiles($xml->css, -1) === false)
{
// Install failed, rollback changes
$this->parent->abort();
return false;
}
// Parse optional tags
$this->parent->parseMedia($xml->media);
$this->parent->parseLanguages($xml->languages, $clientId);
// Get the template description
$this->parent->set('message', JText::_((string) $xml->description));
// Lastly, we will copy the manifest file to its appropriate place.
if (!$this->parent->copyManifest(-1))
{
// Install failed, rollback changes
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_TPL_INSTALL_COPY_SETUP'));
return false;
}
/**
* ---------------------------------------------------------------------------------------------
* Extension Registration
* ---------------------------------------------------------------------------------------------
*/
$row = JTable::getInstance('extension');
if ($this->route == 'update' && $id)
{
$row->load($id);
}
else
{
$row->type = 'template';
$row->element = $this->get('element');
// There is no folder for templates
$row->folder = '';
$row->enabled = 1;
$row->protected = 0;
$row->access = 1;
$row->client_id = $clientId;
$row->params = $this->parent->getParams();
// Custom data
$row->custom_data = '';
}
// Name might change in an update
$row->name = $this->get('name');
$row->manifest_cache = $this->parent->generateManifestCache();
if (!$row->store())
{
// Install failed, roll back changes
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_TPL_INSTALL_ROLLBACK', $db->stderr(true)));
return false;
}
if ($this->route == 'install')
{
$debug = $lang->setDebug(false);
$columns = array($db->quoteName('template'),
$db->quoteName('client_id'),
$db->quoteName('home'),
$db->quoteName('title'),
$db->quoteName('params')
);
$values = array(
$db->quote($row->element), $clientId, $db->quote(0),
$db->quote(JText::sprintf('JLIB_INSTALLER_DEFAULT_STYLE', JText::_($this->get('name')))),
$db->quote($row->params) );
$lang->setDebug($debug);
// Insert record in #__template_styles
$query->clear()
->insert($db->quoteName('#__template_styles'))
->columns($columns)
->values(implode(',', $values));
$db->setQuery($query);
// There is a chance this could fail but we don't care...
$db->execute();
}
return $row->get('extension_id');
}
/**
* Custom update method for components
*
* @return boolean True on success
*
* @since 3.1
*/
public function update()
{
$this->route = 'update';
return $this->install();
}
/**
* Custom uninstall method
*
* @param integer $id The extension ID
*
* @return boolean True on success
*
* @since 3.1
*/
public function uninstall($id)
{
// First order of business will be to load the template object table from the database.
// This should give us the necessary information to proceed.
$row = JTable::getInstance('extension');
if (!$row->load((int) $id) || !strlen($row->element))
{
JLog::add(JText::_('JLIB_INSTALLER_ERROR_TPL_UNINSTALL_ERRORUNKOWNEXTENSION'), JLog::WARNING, 'jerror');
return false;
}
// Is the template we are trying to uninstall a core one?
// Because that is not a good idea...
if ($row->protected)
{
JLog::add(JText::sprintf('JLIB_INSTALLER_ERROR_TPL_UNINSTALL_WARNCORETEMPLATE', $row->name), JLog::WARNING, 'jerror');
return false;
}
$name = $row->element;
$clientId = $row->client_id;
// For a template the id will be the template name which represents the subfolder of the templates folder that the template resides in.
if (!$name)
{
JLog::add(JText::_('JLIB_INSTALLER_ERROR_TPL_UNINSTALL_TEMPLATE_ID_EMPTY'), JLog::WARNING, 'jerror');
return false;
}
// Deny remove default template
$db = $this->parent->getDbo();
$query = "SELECT COUNT(*) FROM #__template_styles WHERE home = '1' AND template = " . $db->quote($name);
$db->setQuery($query);
if ($db->loadResult() != 0)
{
JLog::add(JText::_('JLIB_INSTALLER_ERROR_TPL_UNINSTALL_TEMPLATE_DEFAULT'), JLog::WARNING, 'jerror');
return false;
}
// Get the template root path
$client = JApplicationHelper::getClientInfo($clientId);
if (!$client)
{
JLog::add(JText::_('JLIB_INSTALLER_ERROR_TPL_UNINSTALL_INVALID_CLIENT'), JLog::WARNING, 'jerror');
return false;
}
$this->parent->setPath('extension_root', $client->path . '/templates/' . strtolower($name));
$this->parent->setPath('source', $this->parent->getPath('extension_root'));
// We do findManifest to avoid problem when uninstalling a list of extensions: getManifest cache its manifest file
$this->parent->findManifest();
$manifest = $this->parent->getManifest();
if (!($manifest instanceof SimpleXMLElement))
{
// Kill the extension entry
$row->delete($row->extension_id);
unset($row);
// Make sure we delete the folders
JFolder::delete($this->parent->getPath('extension_root'));
JLog::add(JText::_('JLIB_INSTALLER_ERROR_TPL_UNINSTALL_INVALID_NOTFOUND_MANIFEST'), JLog::WARNING, 'jerror');
return false;
}
// Remove files
$this->parent->removeFiles($manifest->media);
$this->parent->removeFiles($manifest->languages, $clientId);
// Delete the template directory
if (JFolder::exists($this->parent->getPath('extension_root')))
{
$retval = JFolder::delete($this->parent->getPath('extension_root'));
}
else
{
JLog::add(JText::_('JLIB_INSTALLER_ERROR_TPL_UNINSTALL_TEMPLATE_DIRECTORY'), JLog::WARNING, 'jerror');
$retval = false;
}
// Set menu that assigned to the template back to default template
$query = 'UPDATE #__menu'
. ' SET template_style_id = 0'
. ' WHERE template_style_id in ('
. ' SELECT s.id FROM #__template_styles s'
. ' WHERE s.template = ' . $db->quote(strtolower($name)) . ' AND s.client_id = ' . $clientId . ')';
$db->setQuery($query);
$db->execute();
$query = 'DELETE FROM #__template_styles WHERE template = ' . $db->quote($name) . ' AND client_id = ' . $clientId;
$db->setQuery($query);
$db->execute();
$row->delete($row->extension_id);
unset($row);
return $retval;
}
/**
* Discover existing but uninstalled templates
*
* @return array JExtensionTable list
*/
public function discover()
{
$results = array();
$site_list = JFolder::folders(JPATH_SITE . '/templates');
$admin_list = JFolder::folders(JPATH_ADMINISTRATOR . '/templates');
$site_info = JApplicationHelper::getClientInfo('site', true);
$admin_info = JApplicationHelper::getClientInfo('administrator', true);
foreach ($site_list as $template)
{
if ($template == 'system')
{
// Ignore special system template
continue;
}
$manifest_details = JInstaller::parseXMLInstallFile(JPATH_SITE . "/templates/$template/templateDetails.xml");
$extension = JTable::getInstance('extension');
$extension->set('type', 'template');
$extension->set('client_id', $site_info->id);
$extension->set('element', $template);
$extension->set('folder', '');
$extension->set('name', $template);
$extension->set('state', -1);
$extension->set('manifest_cache', json_encode($manifest_details));
$extension->set('params', '{}');
$results[] = $extension;
}
foreach ($admin_list as $template)
{
if ($template == 'system')
{
// Ignore special system template
continue;
}
$manifest_details = JInstaller::parseXMLInstallFile(JPATH_ADMINISTRATOR . "/templates/$template/templateDetails.xml");
$extension = JTable::getInstance('extension');
$extension->set('type', 'template');
$extension->set('client_id', $admin_info->id);
$extension->set('element', $template);
$extension->set('folder', '');
$extension->set('name', $template);
$extension->set('state', -1);
$extension->set('manifest_cache', json_encode($manifest_details));
$extension->set('params', '{}');
$results[] = $extension;
}
return $results;
}
/**
* Discover_install
* Perform an install for a discovered extension
*
* @return boolean
*
* @since 3.1
*/
public function discover_install()
{
// Templates are one of the easiest
// If its not in the extensions table we just add it
$client = JApplicationHelper::getClientInfo($this->parent->extension->client_id);
$manifestPath = $client->path . '/templates/' . $this->parent->extension->element . '/templateDetails.xml';
$this->parent->manifest = $this->parent->isManifest($manifestPath);
$description = (string) $this->parent->manifest->description;
if ($description)
{
$this->parent->set('message', JText::_($description));
}
else
{
$this->parent->set('message', '');
}
$this->parent->setPath('manifest', $manifestPath);
$manifest_details = JInstaller::parseXMLInstallFile($this->parent->getPath('manifest'));
$this->parent->extension->manifest_cache = json_encode($manifest_details);
$this->parent->extension->state = 0;
$this->parent->extension->name = $manifest_details['name'];
$this->parent->extension->enabled = 1;
$data = new JObject;
foreach ($manifest_details as $key => $value)
{
$data->set($key, $value);
}
$this->parent->extension->params = $this->parent->getParams();
if ($this->parent->extension->store())
{
$db = $this->parent->getDbo();
// Insert record in #__template_styles
$lang = JFactory::getLanguage();
$debug = $lang->setDebug(false);
$columns = array($db->quoteName('template'),
$db->quoteName('client_id'),
$db->quoteName('home'),
$db->quoteName('title'),
$db->quoteName('params')
);
$query = $db->getQuery(true)
->insert($db->quoteName('#__template_styles'))
->columns($columns)
->values(
$db->quote($this->parent->extension->element)
. ',' . $db->quote($this->parent->extension->client_id)
. ',' . $db->quote(0)
. ',' . $db->quote(JText::sprintf('JLIB_INSTALLER_DEFAULT_STYLE', $this->parent->extension->name))
. ',' . $db->quote($this->parent->extension->params)
);
$lang->setDebug($debug);
$db->setQuery($query);
$db->execute();
return $this->parent->extension->get('extension_id');
}
else
{
JLog::add(JText::_('JLIB_INSTALLER_ERROR_TPL_DISCOVER_STORE_DETAILS'), JLog::WARNING, 'jerror');
return false;
}
}
/**
* Refreshes the extension table cache
*
* @return boolean Result of operation, true if updated, false on failure
*
* @since 3.1
*/
public function refreshManifestCache()
{
// Need to find to find where the XML file is since we don't store this normally.
$client = JApplicationHelper::getClientInfo($this->parent->extension->client_id);
$manifestPath = $client->path . '/templates/' . $this->parent->extension->element . '/templateDetails.xml';
$this->parent->manifest = $this->parent->isManifest($manifestPath);
$this->parent->setPath('manifest', $manifestPath);
$manifest_details = JInstaller::parseXMLInstallFile($this->parent->getPath('manifest'));
$this->parent->extension->manifest_cache = json_encode($manifest_details);
$this->parent->extension->name = $manifest_details['name'];
try
{
return $this->parent->extension->store();
}
catch (RuntimeException $e)
{
JLog::add(JText::_('JLIB_INSTALLER_ERROR_TPL_REFRESH_MANIFEST_CACHE'), JLog::WARNING, 'jerror');
return false;
}
}
}
/**
* Deprecated class placeholder. You should use JInstallerAdapterTemplate instead.
*
* @package Joomla.Libraries
* @subpackage Installer
* @since 3.1
* @deprecated 4.0
* @codeCoverageIgnore
*/
class JInstallerTemplate extends JInstallerAdapterTemplate
{
}

View File

@ -0,0 +1,167 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage Installer
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
/**
* Extension object
*
* @package Joomla.Libraries
* @subpackage Installer
* @since 3.1
*/
class JInstallerExtension extends JObject
{
/**
* Filename of the extension
*
* @var string
* @since 3.1
*/
public $filename = '';
/**
* Type of the extension
*
* @var string
* @since 3.1
*/
public $type = '';
/**
* Unique Identifier for the extension
*
* @var string
* @since 3.1
*/
public $id = '';
/**
* The status of the extension
*
* @var boolean
* @since 3.1
*/
public $published = false;
/**
* String representation of client. Valid for modules, templates and languages.
* Set by default to site.
*
* @var string
* @since 3.1
*/
public $client = 'site';
/**
* The group name of the plugin. Not used for other known extension types (only plugins)
*
* @var string
* @since 3.1
*/
public $group = '';
/**
* An object representation of the manifest file stored metadata
*
* @var object
* @since 3.1
*/
public $manifest_cache = null;
/**
* An object representation of the extension params
*
* @var object
* @since 3.1
*/
public $params = null;
/**
* Constructor
*
* @param SimpleXMLElement $element A SimpleXMLElement from which to load data from
*
* @since 3.1
*/
public function __construct(SimpleXMLElement $element = null)
{
if ($element)
{
$this->type = (string) $element->attributes()->type;
$this->id = (string) $element->attributes()->id;
switch ($this->type)
{
case 'component':
// By default a component doesn't have anything
break;
case 'module':
case 'template':
case 'language':
$this->client = (string) $element->attributes()->client;
$tmp_client_id = JApplicationHelper::getClientInfo($this->client, 1);
if ($tmp_client_id == null)
{
JLog::add(JText::_('JLIB_INSTALLER_ERROR_EXTENSION_INVALID_CLIENT_IDENTIFIER'), JLog::WARNING, 'jerror');
}
else
{
$this->client_id = $tmp_client_id->id;
}
break;
case 'plugin':
$this->group = (string) $element->attributes()->group;
break;
default:
// Catch all
// Get and set client and group if we don't recognise the extension
if ($element->attributes()->client)
{
$this->client_id = JApplicationHelper::getClientInfo($this->client, 1);
$this->client_id = $this->client_id->id;
}
if ($element->attributes()->group)
{
$this->group = (string) $element->attributes()->group;
}
break;
}
$this->filename = (string) $element;
}
}
}
/**
* Deprecated class placeholder. You should use JInstallerExtension instead.
*
* @package Joomla.Libraries
* @subpackage Installer
* @since 3.1
* @deprecated 4.0
* @codeCoverageIgnore
*/
class JExtension extends JInstallerExtension
{
/**
* Constructor
*
* @param SimpleXMLElement $element A SimpleXMLElement from which to load data from
*
* @since 3.1
*/
public function __construct(SimpleXMLElement $element = null)
{
parent::__construct($element);
}
}

View File

@ -0,0 +1,291 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage Installer
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
jimport('joomla.filesystem.file');
jimport('joomla.filesystem.folder');
jimport('joomla.filesystem.path');
/**
* Installer helper class
*
* @package Joomla.Libraries
* @subpackage Installer
* @since 3.1
*/
abstract class JInstallerHelper
{
/**
* Downloads a package
*
* @param string $url URL of file to download
* @param string $target Download target filename [optional]
*
* @return mixed Path to downloaded package or boolean false on failure
*
* @since 3.1
*/
public static function downloadPackage($url, $target = false)
{
$config = JFactory::getConfig();
// Capture PHP errors
$track_errors = ini_get('track_errors');
ini_set('track_errors', true);
// Set user agent
$version = new JVersion;
ini_set('user_agent', $version->getUserAgent('Installer'));
$http = JHttpFactory::getHttp();
$response = $http->get($url);
if (302 == $response->code && isset($response->headers['Location']))
{
return self::downloadPackage($response->headers['Location']);
}
elseif (200 != $response->code)
{
JLog::add(JText::_('JLIB_INSTALLER_ERROR_DOWNLOAD_SERVER_CONNECT'), JLog::WARNING, 'jerror');
return false;
}
if (isset($response->headers['Content-Disposition']))
{
$contentfilename = explode("\"", $response->headers['Content-Disposition']);
$target = $contentfilename[1];
}
// Set the target path if not given
if (!$target)
{
$target = $config->get('tmp_path') . '/' . self::getFilenameFromURL($url);
}
else
{
$target = $config->get('tmp_path') . '/' . basename($target);
}
// Write buffer to file
JFile::write($target, $response->body);
// Restore error tracking to what it was before
ini_set('track_errors', $track_errors);
// Bump the max execution time because not using built in php zip libs are slow
@set_time_limit(ini_get('max_execution_time'));
// Return the name of the downloaded package
return basename($target);
}
/**
* Unpacks a file and verifies it as a Joomla element package
* Supports .gz .tar .tar.gz and .zip
*
* @param string $p_filename The uploaded package filename or install directory
*
* @return mixed Array on success or boolean false on failure
*
* @since 3.1
*/
public static function unpack($p_filename)
{
// Path to the archive
$archivename = $p_filename;
// Temporary folder to extract the archive into
$tmpdir = uniqid('install_');
// Clean the paths to use for archive extraction
$extractdir = JPath::clean(dirname($p_filename) . '/' . $tmpdir);
$archivename = JPath::clean($archivename);
// Do the unpacking of the archive
try
{
JArchive::extract($archivename, $extractdir);
}
catch (Exception $e)
{
return false;
}
/*
* Let's set the extraction directory and package file in the result array so we can
* cleanup everything properly later on.
*/
$retval['extractdir'] = $extractdir;
$retval['packagefile'] = $archivename;
/*
* Try to find the correct install directory. In case the package is inside a
* subdirectory detect this and set the install directory to the correct path.
*
* List all the items in the installation directory. If there is only one, and
* it is a folder, then we will set that folder to be the installation folder.
*/
$dirList = array_merge(JFolder::files($extractdir, ''), JFolder::folders($extractdir, ''));
if (count($dirList) == 1)
{
if (JFolder::exists($extractdir . '/' . $dirList[0]))
{
$extractdir = JPath::clean($extractdir . '/' . $dirList[0]);
}
}
/*
* We have found the install directory so lets set it and then move on
* to detecting the extension type.
*/
$retval['dir'] = $extractdir;
/*
* Get the extension type and return the directory/type array on success or
* false on fail.
*/
$retval['type'] = self::detectType($extractdir);
if ($retval['type'])
{
return $retval;
}
else
{
return false;
}
}
/**
* Method to detect the extension type from a package directory
*
* @param string $p_dir Path to package directory
*
* @return mixed Extension type string or boolean false on fail
*
* @since 3.1
*/
public static function detectType($p_dir)
{
// Search the install dir for an XML file
$files = JFolder::files($p_dir, '\.xml$', 1, true);
if (!count($files))
{
JLog::add(JText::_('JLIB_INSTALLER_ERROR_NOTFINDXMLSETUPFILE'), JLog::WARNING, 'jerror');
return false;
}
foreach ($files as $file)
{
$xml = simplexml_load_file($file);
if (!$xml)
{
continue;
}
if ($xml->getName() != 'extension')
{
unset($xml);
continue;
}
$type = (string) $xml->attributes()->type;
// Free up memory
unset($xml);
return $type;
}
JLog::add(JText::_('JLIB_INSTALLER_ERROR_NOTFINDJOOMLAXMLSETUPFILE'), JLog::WARNING, 'jerror');
// Free up memory.
unset($xml);
return false;
}
/**
* Gets a file name out of a url
*
* @param string $url URL to get name from
*
* @return mixed String filename or boolean false if failed
*
* @since 3.1
*/
public static function getFilenameFromURL($url)
{
if (is_string($url))
{
$parts = explode('/', $url);
return $parts[count($parts) - 1];
}
return false;
}
/**
* Clean up temporary uploaded package and unpacked extension
*
* @param string $package Path to the uploaded package file
* @param string $resultdir Path to the unpacked extension
*
* @return boolean True on success
*
* @since 3.1
*/
public static function cleanupInstall($package, $resultdir)
{
$config = JFactory::getConfig();
// Does the unpacked extension directory exist?
if (is_dir($resultdir))
{
JFolder::delete($resultdir);
}
// Is the package file a valid file?
if (is_file($package))
{
JFile::delete($package);
}
elseif (is_file(JPath::clean($config->get('tmp_path') . '/' . $package)))
{
// It might also be just a base filename
JFile::delete(JPath::clean($config->get('tmp_path') . '/' . $package));
}
}
/**
* Splits contents of a sql file into array of discreet queries.
* Queries need to be delimited with end of statement marker ';'
*
* @param string $query The SQL statement.
*
* @return array Array of queries
*
* @since 3.1
* @deprecated 13.3 Use JDatabaseDriver::splitSql() directly
* @codeCoverageIgnore
*/
public static function splitSql($query)
{
JLog::add('JInstallerHelper::splitSql() is deprecated. Use JDatabaseDriver::splitSql() instead.', JLog::WARNING, 'deprecated');
$db = JFactory::getDbo();
return $db->splitSql($query);
}
}

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,141 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage Installer
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
jimport('joomla.filesystem.file');
/**
* Joomla! Package Manifest File
*
* @package Joomla.Libraries
* @subpackage Installer
* @since 3.1
*/
abstract class JInstallerManifest
{
/**
* Path to the manifest file
*
* @var string
* @since 3.1
*/
public $manifest_file = '';
/**
* Name of the extension
*
* @var string
* @since 3.1
*/
public $name = '';
/**
* Version of the extension
*
* @var string
* @since 3.1
*/
public $version = '';
/**
* Description of the extension
*
* @var string
* @since 3.1
*/
public $description = '';
/**
* Packager of the extension
*
* @var string
* @since 3.1
*/
public $packager = '';
/**
* Packager's URL of the extension
*
* @var string
* @since 3.1
*/
public $packagerurl = '';
/**
* Update site for the extension
*
* @var string
* @since 3.1
*/
public $update = '';
/**
* List of files in the extension
*
* @var array
* @since 3.1
*/
public $filelist = array();
/**
* Constructor
*
* @param string $xmlpath Path to XML manifest file.
*
* @since 3.1
*/
public function __construct($xmlpath = '')
{
if (strlen($xmlpath))
{
$this->loadManifestFromXML($xmlpath);
}
}
/**
* Load a manifest from a file
*
* @param string $xmlfile Path to file to load
*
* @return boolean
*
* @since 3.1
*/
public function loadManifestFromXML($xmlfile)
{
$this->manifest_file = basename($xmlfile, '.xml');
$xml = simplexml_load_file($xmlfile);
if (!$xml)
{
$this->_errors[] = JText::sprintf('JLIB_INSTALLER_ERROR_LOAD_XML', $xmlfile);
return false;
}
else
{
$this->loadManifestFromData($xml);
return true;
}
}
/**
* Apply manifest data from a SimpleXMLElement to the object.
*
* @param SimpleXMLElement $xml Data to load
*
* @return void
*
* @since 3.1
*/
abstract protected function loadManifestFromData(SimpleXmlElement $xml);
}

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1,108 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage Installer
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
/**
* Joomla! Library Manifest File
*
* @package Joomla.Libraries
* @subpackage Installer
* @since 3.1
*/
class JInstallerManifestLibrary extends JInstallerManifest
{
/**
* File system name of the library
*
* @var string
* @since 3.1
*/
public $libraryname = '';
/**
* Creation Date of the library
*
* @var string
* @since 3.1
*/
public $creationDate = '';
/**
* Copyright notice for the library
*
* @var string
* @since 3.1
*/
public $copyright = '';
/**
* License for the library
*
* @var string
* @since 3.1
*/
public $license = '';
/**
* Author for the library
*
* @var string
* @since 3.1
*/
public $author = '';
/**
* Author email for the library
*
* @var string
* @since 3.1
*/
public $authoremail = '';
/**
* Author URL for the library
*
* @var string
* @since 3.1
*/
public $authorurl = '';
/**
* Apply manifest data from a SimpleXMLElement to the object.
*
* @param SimpleXMLElement $xml Data to load
*
* @return void
*
* @since 3.1
*/
protected function loadManifestFromData(SimpleXMLElement $xml)
{
$this->name = (string) $xml->name;
$this->libraryname = (string) $xml->libraryname;
$this->version = (string) $xml->version;
$this->description = (string) $xml->description;
$this->creationdate = (string) $xml->creationDate;
$this->author = (string) $xml->author;
$this->authoremail = (string) $xml->authorEmail;
$this->authorurl = (string) $xml->authorUrl;
$this->packager = (string) $xml->packager;
$this->packagerurl = (string) $xml->packagerurl;
$this->update = (string) $xml->update;
if (isset($xml->files) && isset($xml->files->file) && count($xml->files->file))
{
foreach ($xml->files->file as $file)
{
$this->filelist[] = (string) $file;
}
}
}
}

View File

@ -0,0 +1,78 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage Installer
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
/**
* Joomla! Package Manifest File
*
* @package Joomla.Libraries
* @subpackage Installer
* @since 3.1
*/
class JInstallerManifestPackage extends JInstallerManifest
{
/**
* Unique name of the package
*
* @var string
* @since 3.1
*/
public $packagename = '';
/**
* Website for the package
*
* @var string
* @since 3.1
*/
public $url = '';
/**
* Scriptfile for the package
*
* @var string
* @since 3.1
*/
public $scriptfile = '';
/**
* Apply manifest data from a SimpleXMLElement to the object.
*
* @param SimpleXMLElement $xml Data to load
*
* @return void
*
* @since 3.1
*/
protected function loadManifestFromData(SimpleXMLElement $xml)
{
$this->name = (string) $xml->name;
$this->packagename = (string) $xml->packagename;
$this->update = (string) $xml->update;
$this->authorurl = (string) $xml->authorUrl;
$this->author = (string) $xml->author;
$this->authoremail = (string) $xml->authorEmail;
$this->description = (string) $xml->description;
$this->packager = (string) $xml->packager;
$this->packagerurl = (string) $xml->packagerurl;
$this->scriptfile = (string) $xml->scriptfile;
$this->version = (string) $xml->version;
if (isset($xml->files->file) && count($xml->files->file))
{
foreach ($xml->files->file as $file)
{
// NOTE: JInstallerExtension doesn't expect a string.
// DO NOT CAST $file
$this->filelist[] = new JInstallerExtension($file);
}
}
}
}

View File

@ -0,0 +1,104 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage helper
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* Utitlity class for associations in multilang
*
* @package Joomla.Libraries
* @subpackage Language
* @since 3.1
*/
class JLanguageAssociations
{
/**
* Get the associations.
*
* @param string $extension The name of the component.
* @param string $tablename The name of the table.
* @param string $context The context
* @param integer $id The primary key value.
* @param string $pk The name of the primary key in the given $table.
* @param string $aliasField If the table has an alias field set it here. Null to not use it
* @param string $catField If the table has a catid field set it here. Null to not use it
*
* @return array The associated items
*
* @since 3.1
*/
public static function getAssociations($extension, $tablename, $context, $id, $pk = 'id', $aliasField = 'alias', $catField = 'catid')
{
$associations = array();
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select($db->quoteName('c2.language'))
->from($db->quoteName($tablename, 'c'))
->join('INNER', $db->quoteName('#__associations', 'a') . ' ON a.id = c.id AND a.context=' . $db->quote($context))
->join('INNER', $db->quoteName('#__associations', 'a2') . ' ON a.key = a2.key')
->join('INNER', $db->quoteName($tablename, 'c2') . ' ON a2.id = c2.' . $db->quoteName($pk));
// Use alias field ?
if (!empty($aliasField))
{
$query->select(
$query->concatenate(
array(
$db->quoteName('c2.' . $pk),
$db->quoteName('c2.' . $aliasField)
),
':'
) . ' AS ' . $db->quoteName($pk)
);
}
else
{
$query->select($db->quoteName('c2.' . $pk));
}
// Use catid field ?
if (!empty($catField))
{
$query->join('INNER', $db->quoteName('#__categories', 'ca') . ' ON ' . $db->quoteName('c2.' . $catField) . ' = ca.id AND ca.extension = ' . $db->quote($extension))
->select(
$query->concatenate(
array('ca.id', 'ca.alias'),
':'
) . ' AS ' . $db->quoteName($catField)
);
}
$query->where('c.' . $pk . ' = ' . (int) $id);
$db->setQuery($query);
try
{
$items = $db->loadObjectList('language');
}
catch (RuntimeException $e)
{
throw new Exception($e->getMessage(), 500);
}
if ($items)
{
foreach ($items as $tag => $item)
{
// Do not return itself as result
if ((int) $item->{$pk} != $id)
{
$associations[$tag] = $item;
}
}
}
return $associations;
}
}

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1,66 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage Language
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('JPATH_PLATFORM') or die;
/**
* Utitlity class for multilang
*
* @package Joomla.Libraries
* @subpackage Language
* @since 2.5.4
*/
class JLanguageMultilang
{
/**
* Method to determine if the language filter plugin is enabled.
* This works for both site and administrator.
*
* @return boolean True if site is supporting multiple languages; false otherwise.
*
* @since 2.5.4
*/
public static function isEnabled()
{
// Flag to avoid doing multiple database queries.
static $tested = false;
// Status of language filter plugin.
static $enabled = false;
// Get application object.
$app = JFactory::getApplication();
// If being called from the front-end, we can avoid the database query.
if ($app->isSite())
{
$enabled = $app->getLanguageFilter();
return $enabled;
}
// If already tested, don't test again.
if (!$tested)
{
// Determine status of language filter plug-in.
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select('enabled')
->from($db->quoteName('#__extensions'))
->where($db->quoteName('type') . ' = ' . $db->quote('plugin'))
->where($db->quoteName('folder') . ' = ' . $db->quote('system'))
->where($db->quoteName('element') . ' = ' . $db->quote('languagefilter'));
$db->setQuery($query);
$enabled = $db->loadResult();
$tested = true;
}
return $enabled;
}
}

View File

@ -0,0 +1,49 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage Layout
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('JPATH_BASE') or die;
/**
* Base class for rendering a display layout
*
* @package Joomla.Libraries
* @subpackage Layout
* @see http://docs.joomla.org/Sharing_layouts_across_views_or_extensions_with_JLayout
* @since 3.0
*/
class JLayoutBase implements JLayout
{
/**
* Method to escape output.
*
* @param string $output The output to escape.
*
* @return string The escaped output.
*
* @since 3.0
*/
public function escape($output)
{
return htmlspecialchars($output, ENT_COMPAT, 'UTF-8');
}
/**
* Method to render the layout.
*
* @param object $displayData Object which properties are used inside the layout file to build displayed output
*
* @return string The necessary HTML to display the layout
*
* @since 3.0
*/
public function render($displayData)
{
return '';
}
}

View File

@ -0,0 +1,110 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage Layout
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('JPATH_BASE') or die;
/**
* Base class for rendering a display layout
* loaded from from a layout file
*
* @package Joomla.Libraries
* @subpackage Layout
* @see http://docs.joomla.org/Sharing_layouts_across_views_or_extensions_with_JLayout
* @since 3.0
*/
class JLayoutFile extends JLayoutBase
{
/**
* @var string Dot separated path to the layout file, relative to base path
* @since 3.0
*/
protected $layoutId = '';
/**
* @var string Base path to use when loading layout files
* @since 3.0
*/
protected $basePath = null;
/**
* @var string Full path to actual layout files, after possible template override check
* @since 3.0.3
*/
protected $fullPath = null;
/**
* Method to instantiate the file-based layout.
*
* @param string $layoutId Dot separated path to the layout file, relative to base path
* @param string $basePath Base path to use when loading layout files
*
* @since 3.0
*/
public function __construct($layoutId, $basePath = null)
{
$this->layoutId = $layoutId;
$this->basePath = is_null($basePath) ? JPATH_ROOT . '/layouts' : rtrim($basePath, DIRECTORY_SEPARATOR);
}
/**
* Method to render the layout.
*
* @param object $displayData Object which properties are used inside the layout file to build displayed output
*
* @return string The necessary HTML to display the layout
*
* @since 3.0
*/
public function render($displayData)
{
$layoutOutput = '';
// Check possible overrides, and build the full path to layout file
$path = $this->getPath();
// If there exists such a layout file, include it and collect its output
if (!empty($path))
{
ob_start();
include $path;
$layoutOutput = ob_get_contents();
ob_end_clean();
}
return $layoutOutput;
}
/**
* Method to finds the full real file path, checking possible overrides
*
* @return string The full path to the layout file
*
* @since 3.0
*/
protected function getPath()
{
jimport('joomla.filesystem.path');
if (is_null($this->fullPath) && !empty($this->layoutId))
{
$rawPath = str_replace('.', '/', $this->layoutId) . '.php';
$fileName = basename($rawPath);
$filePath = dirname($rawPath);
$possiblePaths = array(
JPATH_THEMES . '/' . JFactory::getApplication()->getTemplate() . '/html/layouts/' . $filePath,
$this->basePath . '/' . $filePath
);
$this->fullPath = JPath::find($possiblePaths, $fileName);
}
return $this->fullPath;
}
}

View File

@ -0,0 +1,53 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage Layout
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('JPATH_BASE') or die;
/**
* Helper to render a JLayout object, storing a base path
*
* @package Joomla.Libraries
* @subpackage Layout
* @see http://docs.joomla.org/Sharing_layouts_across_views_or_extensions_with_JLayout
* @since 3.1
*/
class JLayoutHelper
{
/**
* A default base path that will be used if none is provided when calling the render method.
* Note that JLayoutFile itself will defaults to JPATH_ROOT . '/layouts' if no basePath is supplied at all
*
* @var string
* @since 3.1
*/
public static $defaultBasePath = '';
/**
* Method to render the layout.
*
* @param string $layoutFile Dot separated path to the layout file, relative to base path
* @param object $displayData Object which properties are used inside the layout file to build displayed output
* @param string $basePath Base path to use when loading layout files
*
* @return string
*
* @since 3.1
*/
public static function render($layoutFile, $displayData = null, $basePath = '')
{
$basePath = empty($basePath) ? self::$defaultBasePath : $basePath;
// Make sure we send null to JLayoutFile if no path set
$basePath = empty($basePath) ? null : $basePath;
$layout = new JLayoutFile($layoutFile, $basePath);
$renderedLayout = $layout->render($displayData);
return $renderedLayout;
}
}

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1,43 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage Layout
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('JPATH_BASE') or die;
/**
* Interface to handle display layout
*
* @package Joomla.Libraries
* @subpackage Layout
* @see http://docs.joomla.org/Sharing_layouts_across_views_or_extensions_with_JLayout
* @since 3.0
*/
interface JLayout
{
/**
* Method to escape output.
*
* @param string $output The output to escape.
*
* @return string The escaped output.
*
* @since 3.0
*/
public function escape($output);
/**
* Method to render the layout.
*
* @param object $displayData Object which properties are used inside the layout file to build displayed output
*
* @return string The rendered layout.
*
* @since 3.0
*/
public function render($displayData);
}

View File

@ -0,0 +1,21 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage Menu
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* JMenu class.
*
* @package Joomla.Libraries
* @subpackage Menu
* @since 1.5
*/
class JMenuAdministrator extends JMenu
{
}

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

151
libraries/cms/menu/site.php Normal file
View File

@ -0,0 +1,151 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage Menu
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* JMenu class
*
* @package Joomla.Libraries
* @subpackage Menu
* @since 1.5
*/
class JMenuSite extends JMenu
{
/**
* Loads the entire menu table into memory.
*
* @return array
*/
public function load()
{
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select('m.id, m.menutype, m.title, m.alias, m.note, m.path AS route, m.link, m.type, m.level, m.language')
->select($db->quoteName('m.browserNav') . ', m.access, m.params, m.home, m.img, m.template_style_id, m.component_id, m.parent_id')
->select('e.element as component')
->from('#__menu AS m')
->join('LEFT', '#__extensions AS e ON m.component_id = e.extension_id')
->where('m.published = 1')
->where('m.parent_id > 0')
->where('m.client_id = 0')
->order('m.lft');
// Set the query
$db->setQuery($query);
try
{
$this->_items = $db->loadObjectList('id');
}
catch (RuntimeException $e)
{
JError::raiseWarning(500, JText::sprintf('JERROR_LOADING_MENUS', $e->getMessage()));
return false;
}
foreach ($this->_items as &$item)
{
// Get parent information.
$parent_tree = array();
if (isset($this->_items[$item->parent_id]))
{
$parent_tree = $this->_items[$item->parent_id]->tree;
}
// Create tree.
$parent_tree[] = $item->id;
$item->tree = $parent_tree;
// Create the query array.
$url = str_replace('index.php?', '', $item->link);
$url = str_replace('&amp;', '&', $url);
parse_str($url, $item->query);
}
}
/**
* Gets menu items by attribute
*
* @param string $attributes The field name
* @param string $values The value of the field
* @param boolean $firstonly If true, only returns the first item found
*
* @return array
*/
public function getItems($attributes, $values, $firstonly = false)
{
$attributes = (array) $attributes;
$values = (array) $values;
$app = JApplication::getInstance('site');
if ($app->isSite())
{
// Filter by language if not set
if (($key = array_search('language', $attributes)) === false)
{
if (JLanguageMultilang::isEnabled())
{
$attributes[] = 'language';
$values[] = array(JFactory::getLanguage()->getTag(), '*');
}
}
elseif ($values[$key] === null)
{
unset($attributes[$key]);
unset($values[$key]);
}
// Filter by access level if not set
if (($key = array_search('access', $attributes)) === false)
{
$attributes[] = 'access';
$values[] = JFactory::getUser()->getAuthorisedViewLevels();
}
elseif ($values[$key] === null)
{
unset($attributes[$key]);
unset($values[$key]);
}
}
// Reset arrays or we get a notice if some values were unset
$attributes = array_values($attributes);
$values = array_values($values);
return parent::getItems($attributes, $values, $firstonly);
}
/**
* Get menu item by id
*
* @param string $language The language code.
*
* @return object The item object
*
* @since 1.5
*/
public function getDefault($language = '*')
{
if (array_key_exists($language, $this->_default) && JApplication::getInstance('site')->getLanguageFilter())
{
return $this->_items[$this->_default[$language]];
}
elseif (array_key_exists('*', $this->_default))
{
return $this->_items[$this->_default['*']];
}
else
{
return 0;
}
}
}

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1,70 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage Pagination
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
/**
* Pagination object representing a particular item in the pagination lists.
*
* @package Joomla.Libraries
* @subpackage Pagination
* @since 1.5
*/
class JPaginationObject
{
/**
* @var string The link text.
* @since 1.5
*/
public $text;
/**
* @var integer The number of rows as a base offset.
* @since 1.5
*/
public $base;
/**
* @var string The link URL.
* @since 1.5
*/
public $link;
/**
* @var integer The prefix used for request variables.
* @since 1.6
*/
public $prefix;
/**
* @var boolean Flag whether the object is the 'active' page
* @since 3.0
*/
public $active;
/**
* Class constructor.
*
* @param string $text The link text.
* @param integer $prefix The prefix used for request variables.
* @param integer $base The number of rows as a base offset.
* @param string $link The link URL.
* @param boolean $active Flag whether the object is the 'active' page
*
* @since 1.5
*/
public function __construct($text, $prefix = '', $base = null, $link = null, $active = false)
{
$this->text = $text;
$this->prefix = $prefix;
$this->base = $base;
$this->link = $link;
$this->active = $active;
}
}

Some files were not shown because too many files have changed in this diff Show More