| Current Path : /home/w/u/e/wuectly/www/03cbe/ |
| Current File : /home/w/u/e/wuectly/www/03cbe/joomla25.tar |
html/bootstrap.php 0000604 00000073041 15245551626 0010252 0 ustar 00 <?php
/**
* @package Joomla.Libraries
* @subpackage HTML
*
* @copyright Copyright (C) 2005 - 2014 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 = self::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 = self::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)
{
return; // T3 already load framework
}
/**
* 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 = self::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 popover
* @param array $params An array of options for the popover.
* Options for the popover can be:
* animation boolean apply a css fade transition to the popover
* html boolean Insert HTML into the popover. If false, jQuery's text method will be used to insert
* content into the dom.
* placement string|function how to position the popover - top | bottom | left | right
* selector string If a selector is provided, popover objects will be delegated to the specified targets.
* trigger string how popover 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 popover (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 focus';
$opt['content'] = isset($params['content']) ? $params['content'] : null;
$opt['delay'] = isset($params['delay']) ? $params['delay'] : null;
$opt['container'] = isset($params['container']) ? $params['container'] : 'body';
$options = self::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 = self::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'] : true;
$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']) ? $params['container'] : 'body';
$opt['template'] = isset($params['template']) ? (string) $params['template'] : null;
$onShow = isset($params['onShow']) ? (string) $params['onShow'] : null;
$onShown = isset($params['onShown']) ? (string) $params['onShown'] : null;
$onHide = isset($params['onHide']) ? (string) $params['onHide'] : null;
$onHidden = isset($params['onHidden']) ? (string) $params['onHidden'] : null;
$options = self::getJSObject($opt);
// Build the script.
$script = array();
$script[] = "jQuery(document).ready(function(){";
$script[] = "\tjQuery('" . $selector . "').tooltip(" . $options . ");";
if ($onShow)
{
$script[] = "\tjQuery('" . $selector . "').on('show.bs.tooltip', " . $onShow . ");";
}
if ($onShown)
{
$script[] = "\tjQuery('" . $selector . "').on('shown.bs.tooltip', " . $onShown . ");";
}
if ($onHide)
{
$script[] = "\tjQuery('" . $selector . "').on('hide.bs.tooltip', " . $onHide . ");";
}
if ($onHidden)
{
$script[] = "\tjQuery('" . $selector . "').on('hidden.bs.tooltip', " . $onHidden . ");";
}
$script[] = "});";
// Attach tooltips to document
JFactory::getDocument()->addScriptDeclaration(implode("\n", $script));
// 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 = self::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 = self::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);
}
}
/**
* 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 3.0
*/
public static function getJSObject(array $array = array())
{
$elements = array();
foreach ($array as $k => $v)
{
// Don't encode either of these types
if (is_null($v) || is_resource($v))
{
continue;
}
// Safely encode as a Javascript string
$key = json_encode((string) $k);
if (is_bool($v))
{
$elements[] = $key . ': ' . ($v ? 'true' : 'false');
}
elseif (is_numeric($v))
{
$elements[] = $key . ': ' . ($v + 0);
}
elseif (is_string($v))
{
if (strpos($v, '\\') === 0)
{
// Items such as functions and JSON objects are prefixed with \, strip the prefix and don't encode them
$elements[] = $key . ': ' . substr($v, 1);
}
else
{
// The safest way to insert a string
$elements[] = $key . ': ' . json_encode((string) $v);
}
}
else
{
$elements[] = $key . ': ' . static::getJSObject(is_object($v) ? get_object_vars($v) : $v);
}
}
return '{' . implode(',', $elements) . '}';
}
}
html/string.php 0000604 00000021735 15245551626 0007546 0 ustar 00 <?php
/**
* @package Joomla.Platform
* @subpackage HTML
*
* @copyright Copyright (C) 2005 - 2014 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(' ', ' '), ' ', $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(' ', ' ', $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;
}
}
html/jquery.php 0000604 00000005717 15245551626 0007561 0 ustar 00 <?php
/**
* @package Joomla.Libraries
* @subpackage HTML
*
* @copyright Copyright (C) 2005 - 2015 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
*
* @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]
* @param boolean $migrate True to enable the jQuery Migrate plugin
*
* @return void
*
* @since 3.0
*/
public static function framework($noConflict = true, $debug = null, $migrate = true)
{
// 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);
}
// Check if we are loading Migrate
if ($migrate)
{
JHtml::_('script', 'jui/jquery-migrate.min.js', false, true, false, false, $debug);
}
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;
}
}
layout/file.php 0000604 00000033350 15245551626 0007524 0 ustar 00 <?php
/**
* @package Joomla.Libraries
* @subpackage Layout
*
* @copyright Copyright (C) 2005 - 2016 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('JPATH_PLATFORM') or die;
/**
* Base class for rendering a display layout
* loaded from from a layout file
*
* @see https://docs.joomla.org/Sharing_layouts_across_views_or_extensions_with_JLayout
* @since 3.0
*/
class JLayoutFile extends JLayoutBase
{
/**
* Cached layout paths
*
* @var array
* @since 3.5
*/
protected static $cache = array();
/**
* Dot separated path to the layout file, relative to base path
*
* @var string
* @since 3.0
*/
protected $layoutId = '';
/**
* Base path to use when loading layout files
*
* @var string
* @since 3.0
*/
protected $basePath = null;
/**
* Full path to actual layout files, after possible template override check
*
* @var string
* @since 3.0.3
*/
protected $fullPath = null;
/**
* Paths to search for layouts
*
* @var array
* @since 3.2
*/
protected $includePaths = array();
/**
* 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
* @param mixed $options Optional custom options to load. Registry or array format [@since 3.2]
*
* @since 3.0
*/
public function __construct($layoutId, $basePath = null, $options = null)
{
// Initialise / Load options
$this->setOptions($options);
// Main properties
$this->setLayoutId($layoutId);
$this->basePath = $basePath;
// Init Enviroment
$this->setComponent($this->options->get('component', 'auto'));
$this->setClient($this->options->get('client', 'auto'));
}
/**
* Method to render the layout.
*
* @param array $displayData Array of properties available for use inside the layout file to build the displayed output
*
* @return string The necessary HTML to display the layout
*
* @since 3.0
*/
public function render($displayData = array())
{
$this->clearDebugMessages();
// Inherit base output from parent class
$layoutOutput = '';
// Automatically merge any previously data set if $displayData is an array
if (is_array($displayData))
{
$displayData = array_merge($this->data, $displayData);
}
// Check possible overrides, and build the full path to layout file
$path = $this->getPath();
if ($this->isDebugEnabled())
{
echo "<pre>" . $this->renderDebugMessages() . "</pre>";
}
// Nothing to show
if (empty($path))
{
return $layoutOutput;
}
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()
{
JLoader::import('joomla.filesystem.path');
$layoutId = $this->getLayoutId();
$includePaths = $this->getIncludePaths();
$suffixes = $this->getSuffixes();
$this->addDebugMessage('<strong>Layout:</strong> ' . $this->layoutId);
if (!$layoutId)
{
$this->addDebugMessage('<strong>There is no active layout</strong>');
return null;
}
if (!$includePaths)
{
$this->addDebugMessage('<strong>There are no folders to search for layouts:</strong> ' . $layoutId);
return null;
}
$hash = md5(
json_encode(
array(
'paths' => $includePaths,
'suffixes' => $suffixes
)
)
);
if (!empty(static::$cache[$layoutId][$hash]))
{
$this->addDebugMessage('<strong>Cached path:</strong> ' . static::$cache[$layoutId][$hash]);
return static::$cache[$layoutId][$hash];
}
$this->addDebugMessage('<strong>Include Paths:</strong> ' . print_r($includePaths, true));
// Search for suffixed versions. Example: tags.j31.php
if ($suffixes)
{
$this->addDebugMessage('<strong>Suffixes:</strong> ' . print_r($suffixes, true));
foreach ($suffixes as $suffix)
{
$rawPath = str_replace('.', '/', $this->layoutId) . '.' . $suffix . '.php';
$this->addDebugMessage('<strong>Searching layout for:</strong> ' . $rawPath);
if ($foundLayout = JPath::find($this->includePaths, $rawPath))
{
$this->addDebugMessage('<strong>Found layout:</strong> ' . $this->fullPath);
static::$cache[$layoutId][$hash] = $foundLayout;
return static::$cache[$layoutId][$hash];
}
}
}
// Standard version
$rawPath = str_replace('.', '/', $this->layoutId) . '.php';
$this->addDebugMessage('<strong>Searching layout for:</strong> ' . $rawPath);
$foundLayout = JPath::find($this->includePaths, $rawPath);
if (!$foundLayout)
{
$this->addDebugMessage('<strong>Unable to find layout: </strong> ' . $layoutId);
return null;
}
$this->addDebugMessage('<strong>Found layout:</strong> ' . $foundLayout);
static::$cache[$layoutId][$hash] = $foundLayout;
return static::$cache[$layoutId][$hash];
}
/**
* Add one path to include in layout search. Proxy of addIncludePaths()
*
* @param string $path The path to search for layouts
*
* @return self
*
* @since 3.2
*/
public function addIncludePath($path)
{
$this->addIncludePaths($path);
return $this;
}
/**
* Add one or more paths to include in layout search
*
* @param string $paths The path or array of paths to search for layouts
*
* @return self
*
* @since 3.2
*/
public function addIncludePaths($paths)
{
if (empty($paths))
{
return $this;
}
$includePaths = $this->getIncludePaths();
if (is_array($paths))
{
$includePaths = array_unique(array_merge($paths, $includePaths));
}
else
{
array_unshift($includePaths, $paths);
}
$this->setIncludePaths($includePaths);
return $this;
}
/**
* Clear the include paths
*
* @return self
*
* @since 3.5
*/
public function clearIncludePaths()
{
$this->includePaths = array();
return $this;
}
/**
* Get the active include paths
*
* @return array
*
* @since 3.5
*/
public function getIncludePaths()
{
if (empty($this->includePaths))
{
$this->includePaths = $this->getDefaultIncludePaths();
}
return $this->includePaths;
}
/**
* Get the active layout id
*
* @return string
*
* @since 3.5
*/
public function getLayoutId()
{
return $this->layoutId;
}
/**
* Get the active suffixes
*
* @return array
*
* @since 3.5
*/
public function getSuffixes()
{
return $this->getOptions()->get('suffixes', array());
}
/**
* Load the automatically generated language suffixes.
* Example: array('es-ES', 'es', 'ltr')
*
* @return self
*
* @since 3.5
*/
public function loadLanguageSuffixes()
{
$lang = JFactory::getLanguage();
$langTag = $lang->getTag();
$langParts = explode('-', $langTag);
$suffixes = array($langTag, $langParts[0]);
$suffixes[] = $lang->isRTL() ? 'rtl' : 'ltr';
$this->setSuffixes($suffixes);
return $this;
}
/**
* Load the automatically generated version suffixes.
* Example: array('j311', 'j31', 'j3')
*
* @return self
*
* @since 3.5
*/
public function loadVersionSuffixes()
{
$cmsVersion = new JVersion;
// Example j311
$fullVersion = 'j' . str_replace('.', '', $cmsVersion->getShortVersion());
// Create suffixes like array('j311', 'j31', 'j3')
$suffixes = array(
$fullVersion,
substr($fullVersion, 0, 3),
substr($fullVersion, 0, 2),
);
$this->setSuffixes(array_unique($suffixes));
return $this;
}
/**
* Remove one path from the layout search
*
* @param string $path The path to remove from the layout search
*
* @return self
*
* @since 3.2
*/
public function removeIncludePath($path)
{
$this->removeIncludePaths($path);
return $this;
}
/**
* Remove one or more paths to exclude in layout search
*
* @param string $paths The path or array of paths to remove for the layout search
*
* @return self
*
* @since 3.2
*/
public function removeIncludePaths($paths)
{
if (!empty($paths))
{
$paths = (array) $paths;
$this->includePaths = array_diff($this->includePaths, $paths);
}
return $this;
}
/**
* Validate that the active component is valid
*
* @param string $option URL Option of the component. Example: com_content
*
* @return boolean
*
* @since 3.2
*/
protected function validComponent($option = null)
{
// By default we will validate the active component
$component = ($option !== null) ? $option : $this->options->get('component', null);
// Valid option format
if (!empty($component) && substr_count($component, 'com_'))
{
// Latest check: component exists and is enabled
return JComponentHelper::isEnabled($component);
}
return false;
}
/**
* Method to change the component where search for layouts
*
* @param string $option URL Option of the component. Example: com_content
*
* @return mixed Component option string | null for none
*
* @since 3.2
*/
public function setComponent($option)
{
$component = null;
switch ((string) $option)
{
case 'none':
$component = null;
break;
case 'auto':
$component = JApplicationHelper::getComponentName();
break;
default:
$component = $option;
break;
}
// Extra checks
if (!$this->validComponent($component))
{
$component = null;
}
$this->options->set('component', $component);
// Refresh include paths
$this->clearIncludePaths();
}
/**
* Function to initialise the application client
*
* @param mixed $client Frontend: 'site' or 0 | Backend: 'admin' or 1
*
* @return void
*
* @since 3.2
*/
public function setClient($client)
{
// Force string conversion to avoid unexpected states
switch ((string) $client)
{
case 'site':
case '0':
$client = 0;
break;
case 'admin':
case '1':
$client = 1;
break;
default:
$client = (int) T3::isAdmin();
break;
}
$this->options->set('client', $client);
// Refresh include paths
$this->clearIncludePaths();
}
/**
* Change the layout
*
* @param string $layoutId Layout to render
*
* @return self
*
* @since 3.2
*
* @deprecated 3.5 Use setLayoutId()
*/
public function setLayout($layoutId)
{
// Log usage of deprecated function
JLog::add(__METHOD__ . '() is deprecated, use JLayoutFile::setLayoutId() instead.', JLog::WARNING, 'deprecated');
return $this->setLayoutId($layoutId);
}
/**
* Set the active layout id
*
* @param string $layoutId Layout identifier
*
* @return self
*
* @since 3.5
*/
public function setLayoutId($layoutId)
{
$this->layoutId = $layoutId;
$this->fullPath = null;
return $this;
}
/**
* Refresh the list of include paths
*
* @return self
*
* @since 3.2
*
* @deprecated 3.5 Use JLayoutFile::clearIncludePaths()
*/
protected function refreshIncludePaths()
{
// Log usage of deprecated function
JLog::add(__METHOD__ . '() is deprecated, use JLayoutFile::clearIncludePaths() instead.', JLog::WARNING, 'deprecated');
$this->clearIncludePaths();
return $this;
}
/**
* Get the default array of include paths
*
* @return array
*
* @since 3.5
*/
public function getDefaultIncludePaths()
{
// Reset includePaths
$paths = array();
// (1 - highest priority) Received a custom high priority path
if (!is_null($this->basePath))
{
$paths[] = rtrim($this->basePath, DIRECTORY_SEPARATOR);
}
// Component layouts & overrides if exist
$component = $this->options->get('component', null);
if (!empty($component))
{
// (2) Component template overrides path
$paths[] = JPATH_THEMES . '/' . JFactory::getApplication()->getTemplate() . '/html/layouts/' . $component;
// (3) Component path
if ($this->options->get('client') == 0)
{
$paths[] = JPATH_SITE . '/components/' . $component . '/layouts';
}
else
{
$paths[] = JPATH_ADMINISTRATOR . '/components/' . $component . '/layouts';
}
}
// (4.1) - user custom layout overridden
if (!defined('T3_LOCAL_DISABLED')) $paths[] = T3_LOCAL_PATH . '/html/layouts';
// (4) Standard Joomla! layouts overriden
$paths[] = JPATH_THEMES . '/' . JFactory::getApplication()->getTemplate() . '/html/layouts';
// (5.1) - T3 base layout overridden
$paths[] = T3_PATH . '/html/layouts';
// (5 - lower priority) Frontend base layouts
$paths[] = JPATH_ROOT . '/layouts';
return $paths;
}
/**
* Set the include paths to search for layouts
*
* @param array $paths Array with paths to search in
*
* @return self
*
* @since 3.5
*/
public function setIncludePaths($paths)
{
$this->includePaths = (array) $paths;
return $this;
}
/**
* Set suffixes to search layouts
*
* @param mixed $suffixes String with a single suffix or 'auto' | 'none' or array of suffixes
*
* @return self
*
* @since 3.5
*/
public function setSuffixes(array $suffixes)
{
$this->options->set('suffixes', $suffixes);
return $this;
}
/**
* Render a layout with the same include paths & options
*
* @param object $layoutId Object which properties are used inside the layout file to build displayed output
* @param mixed $displayData Data to be rendered
*
* @return string The necessary HTML to display the layout
*
* @since 3.2
*/
public function sublayout($layoutId, $displayData)
{
// Sublayouts are searched in a subfolder with the name of the current layout
if (!empty($this->layoutId))
{
$layoutId = $this->layoutId . '.' . $layoutId;
}
$sublayout = new static($layoutId, $this->basePath, $this->options);
$sublayout->includePaths = $this->includePaths;
return $sublayout->render($displayData);
}
}
layout/base.php 0000604 00000012316 15245551626 0007516 0 ustar 00 <?php
/**
* @package Joomla.Libraries
* @subpackage Layout
*
* @copyright Copyright (C) 2005 - 2016 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('JPATH_PLATFORM') or die;
use Joomla\Registry\Registry;
/**
* Base class for rendering a display layout
*
* @see https://docs.joomla.org/Sharing_layouts_across_views_or_extensions_with_JLayout
* @since 3.0
*/
class JLayoutBase implements JLayout
{
/**
* Options object
*
* @var Registry
* @since 3.2
*/
protected $options = null;
/**
* Data for the layout
*
* @var array
* @since 3.5
*/
protected $data = array();
/**
* Debug information messages
*
* @var array
* @since 3.2
*/
protected $debugMessages = array();
/**
* Set the options
*
* @param array|Registry $options Array / Registry object with the options to load
*
* @return JLayoutBase Instance of $this to allow chaining.
*
* @since 3.2
*/
public function setOptions($options = null)
{
// Received Registry
if ($options instanceof Registry)
{
$this->options = $options;
}
// Received array
elseif (is_array($options))
{
$this->options = new Registry($options);
}
else
{
$this->options = new Registry;
}
return $this;
}
/**
* Get the options
*
* @return Registry Object with the options
*
* @since 3.2
*/
public function getOptions()
{
// Always return a Registry instance
if (!($this->options instanceof Registry))
{
$this->resetOptions();
}
return $this->options;
}
/**
* Function to empty all the options
*
* @return JLayoutBase Instance of $this to allow chaining.
*
* @since 3.2
*/
public function resetOptions()
{
return $this->setOptions(null);
}
/**
* 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');
}
/**
* Get the debug messages array
*
* @return array
*
* @since 3.2
*/
public function getDebugMessages()
{
return $this->debugMessages;
}
/**
* Method to render the layout.
*
* @param array $displayData Array of properties available for use inside the layout file to build the displayed output
*
* @return string The necessary HTML to display the layout
*
* @since 3.0
*/
public function render($displayData)
{
// Automatically merge any previously data set if $displayData is an array
if (is_array($displayData))
{
$displayData = array_merge($this->data, $displayData);
}
return '';
}
/**
* Render the list of debug messages
*
* @return string Output text/HTML code
*
* @since 3.2
*/
public function renderDebugMessages()
{
return implode($this->debugMessages, "\n");
}
/**
* Add a debug message to the debug messages array
*
* @param string $message Message to save
*
* @return self
*
* @since 3.2
*/
public function addDebugMessage($message)
{
$this->debugMessages[] = $message;
return $this;
}
/**
* Clear the debug messages array
*
* @return self
*
* @since 3.5
*/
public function clearDebugMessages()
{
$this->debugMessages = array();
return $this;
}
/**
* Render a layout with debug info
*
* @param mixed $data Data passed to the layout
*
* @return string
*
* @since 3.5
*/
public function debug($data = array())
{
$this->setDebug(true);
$output = $this->render($data);
$this->setDebug(false);
return $output;
}
/**
* Method to get the value from the data array
*
* @param string $key Key to search for in the data array
* @param mixed $defaultValue Default value to return if the key is not set
*
* @return mixed Value from the data array | defaultValue if doesn't exist
*
* @since 3.5
*/
public function get($key, $defaultValue = null)
{
return isset($this->data[$key]) ? $this->data[$key] : $defaultValue;
}
/**
* Get the data being rendered
*
* @return array
*
* @since 3.5
*/
public function getData()
{
return $this->data;
}
/**
* Check if debug mode is enabled
*
* @return boolean
*
* @since 3.5
*/
public function isDebugEnabled()
{
return $this->getOptions()->get('debug', false) === true;
}
/**
* Method to set a value in the data array. Example: $layout->set('items', $items);
*
* @param string $key Key for the data array
* @param mixed $value Value to assign to the key
*
* @return self
*
* @since 3.5
*/
public function set($key, $value)
{
$this->data[(string) $key] = $value;
return $this;
}
/**
* Set the the data passed the layout
*
* @param array $data Array with the data for the layout
*
* @return self
*
* @since 3.5
*/
public function setData(array $data)
{
$this->data = $data;
return $this;
}
/**
* Change the debug mode
*
* @param boolean $debug Enable / Disable debug
*
* @return self
*
* @since 3.5
*/
public function setDebug($debug)
{
$this->options->set('debug', (boolean) $debug);
return $this;
}
}
layout/helper.php 0000604 00000005022 15245551626 0010057 0 ustar 00 <?php
/**
* @package Joomla.Libraries
* @subpackage Layout
*
* @copyright Copyright (C) 2005 - 2016 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('JPATH_PLATFORM') or die;
/**
* Helper to render a JLayout object, storing a base path
*
* @see https://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 a layout with debug info
*
* @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
* @param mixed $options Optional custom options to load. Registry or array format
*
* @return string
*
* @since 3.5
*/
public static function debug($layoutFile, $displayData = null, $basePath = '', $options = null)
{
$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, $options);
$renderedLayout = $layout->debug($displayData);
return $renderedLayout;
}
/**
* 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
* @param mixed $options Optional custom options to load. Registry or array format
*
* @return string
*
* @since 3.1
*/
public static function render($layoutFile, $displayData = null, $basePath = '', $options = null)
{
$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, $options);
$renderedLayout = $layout->render($displayData);
return $renderedLayout;
}
}
layout/layout.php 0000604 00000001640 15245551626 0010117 0 ustar 00 <?php
/**
* @package Joomla.Libraries
* @subpackage Layout
*
* @copyright Copyright (C) 2005 - 2016 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('JPATH_PLATFORM') or die;
/**
* Interface to handle display layout
*
* @see https://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 array $displayData Array of properties available for use inside the layout file to build the displayed output
*
* @return string The rendered layout.
*
* @since 3.0
*/
public function render($displayData);
}
layout/index.html 0000604 00000000037 15245551626 0010065 0 ustar 00 <!DOCTYPE html><title></title>
modulehelper.php 0000604 00000042363 15245551626 0007761 0 ustar 00 <?php
/**
* @package Advanced Module Manager
* @version 3.3.0a
*
* @author Peter van Westen <peter@nonumber.nl>
* @link http://www.nonumber.nl
* @copyright Copyright � 2011 All Rights Reserved
* Brandon IT Consulting (http://www.metamodpro.com)
* NoNumber (http://www.nonumber.nl)
* JoomlArt (http://www.joomlart.com)
* @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
*/
/**
* BASE ON JOOMLA CORE FILE:
* /libraries/joomla/application/module/helper.php
*/
/**
* @package Joomla.Platform
* @subpackage Application
*
* @copyright Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or defined('JPATH_BASE') or die;
jimport('joomla.application.component.helper');
/**
* Module helper class
*
* @package Joomla.Platform
* @subpackage Application
* @since 11.1
*/
abstract class JModuleHelper
{
/**
* Get module by name (real, eg 'Breadcrumbs' or folder, eg 'mod_breadcrumbs')
*
* @param string $name The name of the module
* @param string $title The title of the module, optional
*
* @return object The Module object
*
* @since 11.1
*/
public static function &getModule($name, $title = null)
{
$result = null;
$modules =& JModuleHelper::_load();
$total = count($modules);
for ($i = 0; $i < $total; $i++)
{
// Match the name of the module
if ($modules[$i]->name == $name || $modules[$i]->module == $name)
{
// Match the title if we're looking for a specific instance of the module
if (!$title || $modules[$i]->title == $title)
{
// Found it
$result = &$modules[$i];
break; // Found it
}
}
}
// If we didn't find it, and the name is mod_something, create a dummy object
if (is_null($result) && substr($name, 0, 4) == 'mod_')
{
$result = new stdClass;
$result->id = 0;
$result->title = '';
$result->module = $name;
$result->position = '';
$result->content = '';
$result->showtitle = 0;
$result->control = '';
$result->params = '';
$result->user = 0;
}
return $result;
}
/**
* Get modules by position
*
* @param string $position The position of the module
*
* @return array An array of module objects
*
* @since 11.1
*/
public static function &getModules($position)
{
$position = strtolower($position);
$result = array();
$modules =& JModuleHelper::_load();
$total = count($modules);
for ($i = 0; $i < $total; $i++)
{
if ($modules[$i]->position == $position)
{
$result[] = &$modules[$i];
}
}
if (count($result) == 0)
{
if (JRequest::getBool('tp') && JComponentHelper::getParams('com_templates')->get('template_positions_display'))
{
$result[0] = JModuleHelper::getModule('mod_' . $position);
$result[0]->title = $position;
$result[0]->content = $position;
$result[0]->position = $position;
}
}
return $result;
}
/**
* Checks if a module is enabled
*
* @param string $module The module name
*
* @return boolean
*
* @since 11.1
*/
public static function isEnabled($module)
{
$result = JModuleHelper::getModule($module);
return !is_null($result);
}
/**
* Render the module.
*
* @param object $module A module object.
* @param array $attribs An array of attributes for the module (probably from the XML).
*
* @return string The HTML content of the module output.
*
* @since 11.1
*/
public static function renderModule($module, $attribs = array())
{
static $chrome;
if (constant('JDEBUG'))
{
JProfiler::getInstance('Application')->mark('beforeRenderModule ' . $module->module . ' (' . $module->title . ')');
}
$app = JFactory::getApplication();
// Record the scope.
$scope = $app->scope;
// Set scope to component name
$app->scope = $module->module;
// Get module parameters
$params = new JRegistry;
$params->loadString($module->params);
// Get module path
$module->module = preg_replace('/[^A-Z0-9_\.-]/i', '', $module->module);
$path = JPATH_BASE . '/modules/' . $module->module . '/' . $module->module . '.php';
// Load the module
// $module->user is a check for 1.0 custom modules and is deprecated refactoring
if (empty($module->user) && file_exists($path))
{
$lang = JFactory::getLanguage();
// 1.5 or Core then 1.6 3PD
$lang->load($module->module, JPATH_BASE, null, false, false) ||
$lang->load($module->module, dirname($path), null, false, false) ||
$lang->load($module->module, JPATH_BASE, $lang->getDefault(), false, false) ||
$lang->load($module->module, dirname($path), $lang->getDefault(), false, false);
$content = '';
ob_start();
include $path;
$module->content = ob_get_contents() . $content;
ob_end_clean();
}
// Load the module chrome functions
if (!$chrome)
{
$chrome = array();
}
include_once JPATH_THEMES . '/system/html/modules.php';
$chromePath = JPATH_THEMES . '/' . $app->getTemplate() . '/html/modules.php';
if (!isset($chrome[$chromePath]))
{
if (file_exists($chromePath))
{
include_once $chromePath;
}
$chrome[$chromePath] = true;
}
// Make sure a style is set
if (!isset($attribs['style']))
{
$attribs['style'] = 'none';
}
// Dynamically add outline style
if (JRequest::getBool('tp') && JComponentHelper::getParams('com_templates')->get('template_positions_display'))
{
$attribs['style'] .= ' outline';
}
// Do 3rd party stuff to manipulate module content
// onRenderModule is allowed to alter the $module, $attribs
// and may return a boolean.
// true=remove, any other value = keep.
// $result holds an array of booleans, 1 from each plugin.
// we ditch the module if any of them = true.
$result = $app->triggerEvent( 'onRenderModule', array( &$module, &$attribs ) );
if (!is_array($result)) {
$result = array($result);
}
if ( array_search( true, $result, true ) !== false )
{
return '';
}
foreach (explode(' ', $attribs['style']) as $style)
{
$chromeMethod = 'modChrome_' . $style;
// Apply chrome and render module
if (function_exists($chromeMethod))
{
$module->style = $attribs['style'];
ob_start();
$chromeMethod($module, $params, $attribs);
$module->content = ob_get_contents();
ob_end_clean();
}
}
//revert the scope
$app->scope = $scope;
if (constant('JDEBUG'))
{
JProfiler::getInstance('Application')->mark('afterRenderModule ' . $module->module . ' (' . $module->title . ')');
}
return $module->content;
}
/**
* Get the path to a layout for a module
*
* @param string $module The name of the module
* @param string $layout The name of the module layout. If alternative layout, in the form template:filename.
*
* @return string The path to the module layout
*
* @since 11.1
*/
public static function getLayoutPath($module, $layout = 'default')
{
$template = JFactory::getApplication()->getTemplate();
$defaultLayout = $layout;
if (strpos($layout, ':') !== false)
{
// Get the template and file name from the string
$temp = explode(':', $layout);
$template = ($temp[0] == '_') ? $template : $temp[0];
$layout = $temp[1];
$defaultLayout = ($temp[1]) ? $temp[1] : 'default';
}
// Build the template and base path for the layout
$tPath = JPATH_THEMES . '/' . $template . '/html/' . $module . '/' . $layout . '.php';
$bPath = JPATH_BASE . '/modules/' . $module . '/tmpl/' . $defaultLayout . '.php';
$dPath = JPATH_BASE . '/modules/' . $module . '/tmpl/default.php';
// Do 3rd party stuff to detect layout path for the module
// onGetLayoutPath should return the path to the $layout of $module or false
// $results holds an array of results returned from plugins, 1 from each plugin.
// if a path to the $layout is found and it is a file, return that path
$app = JFactory::getApplication();
$result = $app->triggerEvent( 'onGetLayoutPath', array( $module, $layout ) );
if (is_array($result))
{
foreach ($result as $path)
{
if ($path !== false && is_file ($path))
{
return $path;
}
}
}
// If the template has a layout override use it
if (file_exists($tPath))
{
return $tPath;
}
elseif (file_exists($bPath))
{
return $bPath;
}
else
{
return $dPath;
}
}
/**
* Load published modules.
*
* @return array
*
* @since 11.1
*/
protected static function &_load()
{
static $clean;
if (isset($clean))
{
return $clean;
}
$Itemid = JRequest::getInt('Itemid');
$app = JFactory::getApplication();
$user = JFactory::getUser();
$groups = implode(',', $user->getAuthorisedViewLevels());
$lang = JFactory::getLanguage()->getTag();
$clientId = (int) $app->getClientId();
/*
$cache = JFactory::getCache('com_modules', '');
$cacheid = md5(serialize(array($Itemid, $groups, $clientId, $lang)));
if (!($clean = $cache->get($cacheid)))
{
*/
$db = JFactory::getDbo();
$query = new stdClass;
$query->select = array();
$query->from = array();
$query->join = array();
$query->where = array();
$query->order = array();
$query->select[] = 'm.published, m.id, m.title, m.module, m.position, m.content, m.showtitle, m.params, mm.menuid';
$query->from[] = '#__modules AS m';
$query->join[] = '#__modules_menu AS mm ON mm.moduleid = m.id';
$query->where[] = 'm.published = 1';
$query->join[] = '#__extensions AS e ON e.element = m.module AND e.client_id = m.client_id';
$query->where[] = 'e.enabled = 1';
$date = JFactory::getDate();
$now = $date->toSql();
$nullDate = $db->getNullDate();
$query->where[] = '(m.publish_up = ' . $db->q($nullDate) . ' OR m.publish_up <= ' . $db->q($now) . ')';
$query->where[] = '(m.publish_down = ' . $db->q($nullDate) . ' OR m.publish_down >= ' . $db->q($now) . ')';
$query->where[] = 'm.access IN ('.$groups.')';
$query->where[] = 'm.client_id = ' . $clientId;
$query->where[] = '(mm.menuid = ' . (int) $Itemid . ' OR mm.menuid <= 0)';
// Filter by language
if ($app->isClient('site') && $app->getLanguageFilter())
{
$query->where[] = 'm.language IN (' . $db->q($lang) . ',' . $db->q('*') . ')';
}
$query->order[] = 'm.position, m.ordering';
// Do 3rd party stuff to change query
$app->triggerEvent( 'onCreateModuleQuery', array( &$query ) );
$q = $db->getQuery(true);
// convert array object to query object
foreach ( $query as $type => $strings )
{
foreach ( $strings as $string )
{
if ( $type == 'join' )
{
$q->{$type}( 'LEFT', $string );
}
else
{
$q->{$type}( $string );
}
}
}
// Set the query
$db->setQuery($q);
$modules = $db->loadObjectList();
$clean = array();
if ($db->getErrorNum())
{
JError::raiseWarning(500, JText::sprintf('JLIB_APPLICATION_ERROR_MODULE_LOAD', $db->getErrorMsg()));
return $clean;
}
// Apply negative selections and eliminate duplicates
$negId = $Itemid ? -(int) $Itemid : false;
$dupes = array();
for ($i = 0, $n = count($modules); $i < $n; $i++)
{
$module = &$modules[$i];
// The module is excluded if there is an explicit prohibition
$negHit = ($negId === (int) $module->menuid);
if (isset($dupes[$module->id]))
{
// If this item has been excluded, keep the duplicate flag set,
// but remove any item from the cleaned array.
if ($negHit)
{
unset($clean[$module->id]);
}
continue;
}
$dupes[$module->id] = true;
// Only accept modules without explicit exclusions.
if (!$negHit)
{
// Determine if this is a 1.0 style custom module (no mod_ prefix)
// This should be eliminated when the class is refactored.
// $module->user is deprecated.
$file = $module->module;
$custom = substr($file, 0, 4) == 'mod_' ? 0 : 1;
$module->user = $custom;
// 1.0 style custom module name is given by the title field, otherwise strip off "mod_"
$module->name = $custom ? $module->module : substr($file, 4);
$module->style = null;
$module->position = strtolower($module->position);
$clean[$module->id] = $module;
}
}
unset($dupes);
// Do 3rd party stuff to manipulate module array.
// Any plugins using this architecture may make alterations to the referenced $modules array.
// To remove items you can do unset($modules[n]) or $modules[n]->published = false.
// "onPrepareModuleList" may alter or add $modules, and does not need to return anything.
// This should be used for module addition/deletion that the user would expect to happen at an
// early stage.
$app->triggerEvent( 'onPrepareModuleList', array( &$clean ) );
// "onAlterModuleList" may alter or add $modules, and does not need to return anything.
$app->triggerEvent( 'onAlterModuleList', array( &$clean ) );
// "onPostProcessModuleList" allows a plugin to perform actions like parameter changes
// on the completed list of modules and is guaranteed to occur *after*
// the earlier plugins.
$app->triggerEvent( 'onPostProcessModuleList', array( &$clean ) );
// Remove any that were marked as disabled during the preceding steps
foreach ( $clean as $id => $module )
{
if ( !isset( $module->published ) || $module->published == 0 )
{
unset( $clean[$id] );
}
}
// Return to simple indexing that matches the query order.
$clean = array_values($clean);
/*
$cache->store($clean, $cacheid);
}
*/
return $clean;
}
/**
* Module cache helper
*
* Caching modes:
* To be set in XML:
* 'static' One cache file for all pages with the same module parameters
* 'oldstatic' 1.5 definition of module caching, one cache file for all pages
* with the same module id and user aid,
* 'itemid' Changes on itemid change, to be called from inside the module:
* 'safeuri' Id created from $cacheparams->modeparams array,
* 'id' Module sets own cache id's
*
* @param object $module Module object
* @param object $moduleparams Module parameters
* @param object $cacheparams Module cache parameters - id or url parameters, depending on the module cache mode
*
* @return string
*
* @since 11.1
*
* @link JFilterInput::clean()
*/
public static function moduleCache($module, $moduleparams, $cacheparams)
{
if (!isset($cacheparams->modeparams))
{
$cacheparams->modeparams = null;
}
// Add module ID to fix problem of cache for modules with the same type
if ($cacheparams->modeparams && is_string($cacheparams->modeparams)) {
$cacheparams->modeparams .= ":".$module->id;
}
if (!isset($cacheparams->cachegroup))
{
$cacheparams->cachegroup = $module->module;
}
$user = JFactory::getUser();
$cache = JFactory::getCache($cacheparams->cachegroup, 'callback');
$conf = JFactory::getConfig();
// Turn cache off for internal callers if parameters are set to off and for all logged in users
if ($moduleparams->get('owncache', null) === '0' || $conf->get('caching') == 0 || $user->get('id'))
{
$cache->setCaching(false);
}
// module cache is set in seconds, global cache in minutes, setLifeTime works in minutes
$cache->setLifeTime($moduleparams->get('cache_time', $conf->get('cachetime') * 60) / 60);
$wrkaroundoptions = array('nopathway' => 1, 'nohead' => 0, 'nomodules' => 1, 'modulemode' => 1, 'mergehead' => 1);
$wrkarounds = true;
$view_levels = md5(serialize($user->getAuthorisedViewLevels()));
switch ($cacheparams->cachemode)
{
case 'id':
$ret = $cache->get(
array($cacheparams->class, $cacheparams->method),
$cacheparams->methodparams,
$cacheparams->modeparams,
$wrkarounds,
$wrkaroundoptions
);
break;
case 'safeuri':
$secureid = null;
if (is_array($cacheparams->modeparams))
{
$uri = JRequest::get();
$safeuri = new stdClass;
foreach ($cacheparams->modeparams as $key => $value)
{
// Use int filter for id/catid to clean out spamy slugs
if (isset($uri[$key]))
{
$safeuri->$key = JRequest::_cleanVar($uri[$key], 0, $value);
}
}
}
$secureid = md5(serialize(array($safeuri, $cacheparams->method, $moduleparams)));
$ret = $cache->get(
array($cacheparams->class, $cacheparams->method),
$cacheparams->methodparams,
$module->id . $view_levels . $secureid,
$wrkarounds,
$wrkaroundoptions
);
break;
case 'static':
$ret = $cache->get(
array($cacheparams->class,
$cacheparams->method),
$cacheparams->methodparams,
$module->module . md5(serialize($cacheparams->methodparams)),
$wrkarounds,
$wrkaroundoptions
);
break;
case 'oldstatic': // provided for backward compatibility, not really usefull
$ret = $cache->get(
array($cacheparams->class, $cacheparams->method),
$cacheparams->methodparams,
$module->id . $view_levels,
$wrkarounds,
$wrkaroundoptions
);
break;
case 'itemid':
default:
$ret = $cache->get(
array($cacheparams->class, $cacheparams->method),
$cacheparams->methodparams,
$module->id . $view_levels . JRequest::getVar('Itemid', null, 'default', 'INT'),
$wrkarounds,
$wrkaroundoptions
);
break;
}
return $ret;
}
}
view.php 0000604 00000044321 15245551626 0006242 0 ustar 00 <?php
/**
* @package Joomla.Platform
* @subpackage Application
*
* @copyright Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
/**
* Base class for a Joomla View
*
* Class holding methods for displaying presentation data.
*
* @package Joomla.Platform
* @subpackage Application
* @since 11.1
*/
class JView extends JObject
{
/**
* The name of the view
*
* @var array
*/
protected $_name = null;
/**
* Registered models
*
* @var array
*/
protected $_models = array();
/**
* The base path of the view
*
* @var string
*/
protected $_basePath = null;
/**
* The default model
*
* @var string
*/
protected $_defaultModel = null;
/**
* Layout name
*
* @var string
*/
protected $_layout = 'default';
/**
* Layout extension
*
* @var string
*/
protected $_layoutExt = 'php';
/**
* Layout template
*
* @var string
*/
protected $_layoutTemplate = '_';
/**
* The set of search directories for resources (templates)
*
* @var array
*/
protected $_path = array('template' => array(), 'helper' => array());
/**
* The name of the default template source file.
*
* @var string
*/
protected $_template = null;
/**
* The output of the template script.
*
* @var string
*/
protected $_output = null;
/**
* Callback for escaping.
*
* @var string
*/
protected $_escape = 'htmlspecialchars';
/**
* Charset to use in escaping mechanisms; defaults to urf8 (UTF-8)
*
* @var string
*/
protected $_charset = 'UTF-8';
/**
* Constructor
*
* @param array $config A named configuration array for object construction.<br/>
* name: the name (optional) of the view (defaults to the view class name suffix).<br/>
* charset: the character set to use for display<br/>
* escape: the name (optional) of the function to use for escaping strings<br/>
* base_path: the parent path (optional) of the views directory (defaults to the component folder)<br/>
* template_plath: the path (optional) of the layout directory (defaults to base_path + /views/ + view name<br/>
* helper_path: the path (optional) of the helper files (defaults to base_path + /helpers/)<br/>
* layout: the layout (optional) to use to display the view<br/>
*
* @since 11.1
*/
public function __construct($config = array())
{
// Set the view name
if (empty($this->_name))
{
if (array_key_exists('name', $config))
{
$this->_name = $config['name'];
}
else
{
$this->_name = $this->getName();
}
}
// Set the charset (used by the variable escaping functions)
if (array_key_exists('charset', $config))
{
$this->_charset = $config['charset'];
}
// User-defined escaping callback
if (array_key_exists('escape', $config))
{
$this->setEscape($config['escape']);
}
// Set a base path for use by the view
if (array_key_exists('base_path', $config))
{
$this->_basePath = $config['base_path'];
}
else
{
$this->_basePath = JPATH_COMPONENT;
}
// Set the default template search path
if (array_key_exists('template_path', $config))
{
// User-defined dirs
$this->_setPath('template', $config['template_path']);
}
else
{
$this->_setPath('template', $this->_basePath . '/views/' . $this->getName() . '/tmpl');
}
// Set the default helper search path
if (array_key_exists('helper_path', $config))
{
// User-defined dirs
$this->_setPath('helper', $config['helper_path']);
}
else
{
$this->_setPath('helper', $this->_basePath . '/helpers');
}
// Set the layout
if (array_key_exists('layout', $config))
{
$this->setLayout($config['layout']);
}
else
{
$this->setLayout('default');
}
$this->baseurl = JURI::base(true);
}
/**
* Execute and display a template script.
*
* @param string $tpl The name of the template file to parse; automatically searches through the template paths.
*
* @return mixed A string if successful, otherwise a JError object.
*
* @see fetch()
* @since 11.1
*/
public function display($tpl = null)
{
$result = $this->loadTemplate($tpl);
if ($result instanceof Exception)
{
return $result;
}
echo $result;
}
/**
* Assigns variables to the view script via differing strategies.
*
* This method is overloaded; you can assign all the properties of
* an object, an associative array, or a single value by name.
*
* You are not allowed to set variables that begin with an underscore;
* these are either private properties for JView or private variables
* within the template script itself.
*
* <code>
* $view = new JView;
*
* // Assign directly
* $view->var1 = 'something';
* $view->var2 = 'else';
*
* // Assign by name and value
* $view->assign('var1', 'something');
* $view->assign('var2', 'else');
*
* // Assign by assoc-array
* $ary = array('var1' => 'something', 'var2' => 'else');
* $view->assign($obj);
*
* // Assign by object
* $obj = new stdClass;
* $obj->var1 = 'something';
* $obj->var2 = 'else';
* $view->assign($obj);
*
* </code>
*
* @return boolean True on success, false on failure.
*/
public function assign()
{
// Get the arguments; there may be 1 or 2.
$arg0 = @func_get_arg(0);
$arg1 = @func_get_arg(1);
// Assign by object
if (is_object($arg0))
{
// Assign public properties
foreach (get_object_vars($arg0) as $key => $val)
{
if (substr($key, 0, 1) != '_')
{
$this->$key = $val;
}
}
return true;
}
// Assign by associative array
if (is_array($arg0))
{
foreach ($arg0 as $key => $val)
{
if (substr($key, 0, 1) != '_')
{
$this->$key = $val;
}
}
return true;
}
// Assign by string name and mixed value.
// We use array_key_exists() instead of isset() because isset()
// fails if the value is set to null.
if (is_string($arg0) && substr($arg0, 0, 1) != '_' && func_num_args() > 1)
{
$this->$arg0 = $arg1;
return true;
}
// $arg0 was not object, array, or string.
return false;
}
/**
* Assign variable for the view (by reference).
*
* You are not allowed to set variables that begin with an underscore;
* these are either private properties for JView or private variables
* within the template script itself.
*
* <code>
* $view = new JView;
*
* // Assign by name and value
* $view->assignRef('var1', $ref);
*
* // Assign directly
* $view->ref = &$var1;
* </code>
*
* @param string $key The name for the reference in the view.
* @param mixed &$val The referenced variable.
*
* @return boolean True on success, false on failure.
*
* @since 11.1
*/
public function assignRef($key, &$val)
{
if (is_string($key) && substr($key, 0, 1) != '_')
{
$this->$key = &$val;
return true;
}
return false;
}
/**
* Escapes a value for output in a view script.
*
* If escaping mechanism is either htmlspecialchars or htmlentities, uses
* {@link $_encoding} setting.
*
* @param mixed $var The output to escape.
*
* @return mixed The escaped value.
*
* @since 11.1
*/
public function escape($var)
{
if (in_array($this->_escape, array('htmlspecialchars', 'htmlentities')))
{
return call_user_func($this->_escape, $var, ENT_COMPAT, $this->_charset);
}
return call_user_func($this->_escape, $var);
}
/**
* Method to get data from a registered model or a property of the view
*
* @param string $property The name of the method to call on the model or the property to get
* @param string $default The name of the model to reference or the default value [optional]
*
* @return mixed The return value of the method
*
* @since 11.1
*/
public function get($property, $default = null)
{
// If $model is null we use the default model
if (is_null($default))
{
$model = $this->_defaultModel;
}
else
{
$model = strtolower($default);
}
// First check to make sure the model requested exists
if (isset($this->_models[$model]))
{
// Model exists, let's build the method name
$method = 'get' . ucfirst($property);
// Does the method exist?
if (method_exists($this->_models[$model], $method))
{
// The method exists, let's call it and return what we get
$result = $this->_models[$model]->$method();
return $result;
}
}
// Degrade to JObject::get
$result = parent::get($property, $default);
return $result;
}
/**
* Method to get the model object
*
* @param string $name The name of the model (optional)
*
* @return mixed JModel object
*
* @since 11.1
*/
public function getModel($name = null)
{
if ($name === null)
{
$name = $this->_defaultModel;
}
return $this->_models[strtolower($name)];
}
/**
* Get the layout.
*
* @return string The layout name
*/
public function getLayout()
{
return $this->_layout;
}
/**
* Get the layout template.
*
* @return string The layout template name
*/
public function getLayoutTemplate()
{
return $this->_layoutTemplate;
}
/**
* Method to get the view name
*
* The model name by default parsed using the classname, or it can be set
* by passing a $config['name'] in the class constructor
*
* @return string The name of the model
*
* @since 11.1
*/
public function getName()
{
if (empty($this->_name))
{
$r = null;
if (!preg_match('/View((view)*(.*(view)?.*))$/i', get_class($this), $r))
{
JError::raiseError(500, JText::_('JLIB_APPLICATION_ERROR_VIEW_GET_NAME'));
}
if (strpos($r[3], "view"))
{
JError::raiseWarning('SOME_ERROR_CODE', JText::_('JLIB_APPLICATION_ERROR_VIEW_GET_NAME_SUBSTRING'));
}
$this->_name = strtolower($r[3]);
}
return $this->_name;
}
/**
* Method to add a model to the view. We support a multiple model single
* view system by which models are referenced by classname. A caveat to the
* classname referencing is that any classname prepended by JModel will be
* referenced by the name without JModel, eg. JModelCategory is just
* Category.
*
* @param JModel &$model The model to add to the view.
* @param boolean $default Is this the default model?
*
* @return object The added model.
*
* @since 11.1
*/
public function setModel(&$model, $default = false)
{
$name = strtolower($model->getName());
$this->_models[$name] = &$model;
if ($default)
{
$this->_defaultModel = $name;
}
return $model;
}
/**
* Sets the layout name to use
*
* @param string $layout The layout name or a string in format <template>:<layout file>
*
* @return string Previous value.
*
* @since 11.1
*/
public function setLayout($layout)
{
$previous = $this->_layout;
if (strpos($layout, ':') === false)
{
$this->_layout = $layout;
}
else
{
// Convert parameter to array based on :
$temp = explode(':', $layout);
$this->_layout = $temp[1];
// Set layout template
$this->_layoutTemplate = $temp[0];
}
return $previous;
}
/**
* Allows a different extension for the layout files to be used
*
* @param string $value The extension.
*
* @return string Previous value
*
* @since 11.1
*/
public function setLayoutExt($value)
{
$previous = $this->_layoutExt;
if ($value = preg_replace('#[^A-Za-z0-9]#', '', trim($value)))
{
$this->_layoutExt = $value;
}
return $previous;
}
/**
* Sets the _escape() callback.
*
* @param mixed $spec The callback for _escape() to use.
*
* @return void
*
* @since 11.1
*/
public function setEscape($spec)
{
$this->_escape = $spec;
}
/**
* Adds to the stack of view script paths in LIFO order.
*
* @param mixed $path A directory path or an array of paths.
*
* @return void
*
* @since 11.1
*/
public function addTemplatePath($path)
{
$this->_addPath('template', $path);
}
/**
* Adds to the stack of helper script paths in LIFO order.
*
* @param mixed $path A directory path or an array of paths.
*
* @return void
*
* @since 11.1
*/
public function addHelperPath($path)
{
$this->_addPath('helper', $path);
}
/**
* Load a template file -- first look in the templates folder for an override
*
* @param string $tpl The name of the template source file; automatically searches the template paths and compiles as needed.
*
* @return string The output of the the template script.
*
* @since 11.1
*/
public function loadTemplate($tpl = null)
{
// Clear prior output
$this->_output = null;
$template = JFactory::getApplication()->getTemplate();
$layout = $this->getLayout();
$layoutTemplate = $this->getLayoutTemplate();
// Create the template file name based on the layout
$file = isset($tpl) ? $layout . '_' . $tpl : $layout;
// Clean the file name
$file = preg_replace('/[^A-Z0-9_\.-]/i', '', $file);
$tpl = isset($tpl) ? preg_replace('/[^A-Z0-9_\.-]/i', '', $tpl) : $tpl;
// Load the language file for the template
$lang = JFactory::getLanguage();
$lang->load('tpl_' . $template, JPATH_BASE, null, false, false)
|| $lang->load('tpl_' . $template, JPATH_THEMES . "/$template", null, false, false)
|| $lang->load('tpl_' . $template, JPATH_BASE, $lang->getDefault(), false, false)
|| $lang->load('tpl_' . $template, JPATH_THEMES . "/$template", $lang->getDefault(), false, false);
// Change the template folder if alternative layout is in different template
if (isset($layoutTemplate) && $layoutTemplate != '_' && $layoutTemplate != $template)
{
$this->_path['template'] = str_replace($template, $layoutTemplate, $this->_path['template']);
}
// Load the template script
jimport('joomla.filesystem.path');
$filetofind = $this->_createFileName('template', array('name' => $file));
$this->_template = JPath::find($this->_path['template'], $filetofind);
// If alternate layout can't be found, fall back to default layout
if ($this->_template == false)
{
$filetofind = $this->_createFileName('', array('name' => 'default' . (isset($tpl) ? '_' . $tpl : $tpl)));
$this->_template = JPath::find($this->_path['template'], $filetofind);
}
if ($this->_template != false)
{
// Unset so as not to introduce into template scope
unset($tpl);
unset($file);
// Never allow a 'this' property
if (isset($this->this))
{
unset($this->this);
}
// Start capturing output into a buffer
ob_start();
// Include the requested template filename in the local scope
// (this will execute the view logic).
include $this->_template;
// Done with the requested template; get the buffer and
// clear it.
$this->_output = ob_get_contents();
ob_end_clean();
return $this->_output;
}
else
{
return JError::raiseError(500, JText::sprintf('JLIB_APPLICATION_ERROR_LAYOUTFILE_NOT_FOUND', $file));
}
}
/**
* Load a helper file
*
* @param string $hlp The name of the helper source file automatically searches the helper paths and compiles as needed.
*
* @return void
*
* @since 11.1
*/
public function loadHelper($hlp = null)
{
// Clean the file name
$file = preg_replace('/[^A-Z0-9_\.-]/i', '', $hlp);
// Load the template script
jimport('joomla.filesystem.path');
$helper = JPath::find($this->_path['helper'], $this->_createFileName('helper', array('name' => $file)));
if ($helper != false)
{
// Include the requested template filename in the local scope
include_once $helper;
}
}
/**
* Sets an entire array of search paths for templates or resources.
*
* @param string $type The type of path to set, typically 'template'.
* @param mixed $path The new search path, or an array of search paths. If null or false, resets to the current directory only.
*
* @return void
*
* @since 11.1
*/
protected function _setPath($type, $path)
{
$component = JApplicationHelper::getComponentName();
$app = JFactory::getApplication();
// Clear out the prior search dirs
$this->_path[$type] = array();
// Actually add the user-specified directories
$this->_addPath($type, $path);
// Always add the fallback directories as last resort
switch (strtolower($type))
{
case 'template':
// Set the alternative template search dir
if (isset($app))
{
$component = preg_replace('/[^A-Z0-9_\.-]/i', '', $component);
//if it is T3 template, update search path for template
$this->_addPath('template', T3_PATH . '/html/' . $component . '/' . $this->getName());
$fallback = JPATH_THEMES . '/' . $app->getTemplate() . '/html/' . $component . '/' . $this->getName();
$this->_addPath('template', $fallback);
//search path for user custom folder
if (!defined('T3_LOCAL_DISABLED')) $this->_addPath('template', T3_LOCAL_PATH . '/html/' . $component . '/' . $this->getName());
}
break;
}
}
/**
* Adds to the search path for templates and resources.
*
* @param string $type The type of path to add.
* @param mixed $path The directory or stream, or an array of either, to search.
*
* @return void
*
* @since 11.1
*/
protected function _addPath($type, $path)
{
// Just force to array
settype($path, 'array');
// Loop through the path directories
foreach ($path as $dir)
{
// no surrounding spaces allowed!
$dir = trim($dir);
// Add trailing separators as needed
if (substr($dir, -1) != DIRECTORY_SEPARATOR)
{
// Directory
$dir .= DIRECTORY_SEPARATOR;
}
// Add to the top of the search dirs
array_unshift($this->_path[$type], $dir);
}
}
/**
* Create the filename for a resource
*
* @param string $type The resource type to create the filename for
* @param array $parts An associative array of filename information
*
* @return string The filename
*
* @since 11.1
*/
protected function _createFileName($type, $parts = array())
{
$filename = '';
switch ($type)
{
case 'template':
$filename = strtolower($parts['name']) . '.' . $this->_layoutExt;
break;
default:
$filename = strtolower($parts['name']) . '.php';
break;
}
return $filename;
}
}
pagination.php 0000604 00000047375 15245551626 0007435 0 ustar 00 <?php
/**
* @package Joomla.Platform
* @subpackage HTML
*
* @copyright Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
/**
* Pagination Class. Provides a common interface for content pagination for the
* Joomla! Platform.
*
* @package Joomla.Platform
* @subpackage HTML
* @since 11.1
*/
class JPagination extends JObject
{
/**
* @var integer The record number to start displaying from.
* @since 11.1
*/
public $limitstart = null;
/**
* @var integer Number of rows to display per page.
* @since 11.1
*/
public $limit = null;
/**
* @var integer Total number of rows.
* @since 11.1
*/
public $total = null;
/**
* @var integer Prefix used for request variables.
* @since 11.1
*/
public $prefix = null;
/**
* @var boolean View all flag
* @since 11.1
*/
protected $_viewall = false;
/**
* Additional URL parameters to be added to the pagination URLs generated by the class. These
* may be useful for filters and extra values when dealing with lists and GET requests.
*
* @var array
* @since 11.1
*/
protected $_additionalUrlParams = array();
/**
* Constructor.
*
* @param integer $total The total number of items.
* @param integer $limitstart The offset of the item to start at.
* @param integer $limit The number of items to display per page.
* @param string $prefix The prefix used for request variables.
*
* @since 11.1
*/
public function __construct($total, $limitstart, $limit, $prefix = '')
{
// Value/type checking.
$this->total = (int) $total;
$this->limitstart = (int) max($limitstart, 0);
$this->limit = (int) max($limit, 0);
$this->prefix = $prefix;
if ($this->limit > $this->total)
{
$this->limitstart = 0;
}
if (!$this->limit)
{
$this->limit = $total;
$this->limitstart = 0;
}
/*
* If limitstart is greater than total (i.e. we are asked to display records that don't exist)
* then set limitstart to display the last natural page of results
*/
if ($this->limitstart > $this->total - $this->limit)
{
$this->limitstart = max(0, (int) (ceil($this->total / $this->limit) - 1) * $this->limit);
}
// Set the total pages and current page values.
if ($this->limit > 0)
{
$this->set('pages.total', ceil($this->total / $this->limit));
$this->set('pages.current', ceil(($this->limitstart + 1) / $this->limit));
}
// Set the pagination iteration loop values.
$displayedPages = 10;
$this->set('pages.start', $this->get('pages.current') - ($displayedPages / 2));
if ($this->get('pages.start') < 1)
{
$this->set('pages.start', 1);
}
if (($this->get('pages.start') + $displayedPages) > $this->get('pages.total'))
{
$this->set('pages.stop', $this->get('pages.total'));
if ($this->get('pages.total') < $displayedPages)
{
$this->set('pages.start', 1);
}
else
{
$this->set('pages.start', $this->get('pages.total') - $displayedPages + 1);
}
}
else
{
$this->set('pages.stop', ($this->get('pages.start') + $displayedPages - 1));
}
// If we are viewing all records set the view all flag to true.
if ($limit == 0)
{
$this->_viewall = true;
}
}
/**
* Method to set an additional URL parameter to be added to all pagination class generated
* links.
*
* @param string $key The name of the URL parameter for which to set a value.
* @param mixed $value The value to set for the URL parameter.
*
* @return mixed The old value for the parameter.
*
* @since 11.1
*/
public function setAdditionalUrlParam($key, $value)
{
// Get the old value to return and set the new one for the URL parameter.
$result = isset($this->_additionalUrlParams[$key]) ? $this->_additionalUrlParams[$key] : null;
// If the passed parameter value is null unset the parameter, otherwise set it to the given value.
if ($value === null)
{
unset($this->_additionalUrlParams[$key]);
}
else
{
$this->_additionalUrlParams[$key] = $value;
}
return $result;
}
/**
* Method to get an additional URL parameter (if it exists) to be added to
* all pagination class generated links.
*
* @param string $key The name of the URL parameter for which to get the value.
*
* @return mixed The value if it exists or null if it does not.
*
* @since 11.1
*/
public function getAdditionalUrlParam($key)
{
$result = isset($this->_additionalUrlParams[$key]) ? $this->_additionalUrlParams[$key] : null;
return $result;
}
/**
* Return the rationalised offset for a row with a given index.
*
* @param integer $index The row index
*
* @return integer Rationalised offset for a row with a given index.
*
* @since 11.1
*/
public function getRowOffset($index)
{
return $index + 1 + $this->limitstart;
}
/**
* Return the pagination data object, only creating it if it doesn't already exist.
*
* @return object Pagination data object.
*
* @since 11.1
*/
public function getData()
{
static $data;
if (!is_object($data))
{
$data = $this->_buildDataObject();
}
return $data;
}
/**
* Create and return the pagination pages counter string, ie. Page 2 of 4.
*
* @return string Pagination pages counter string.
*
* @since 11.1
*/
public function getPagesCounter()
{
// Initialise variables.
$html = null;
if ($this->get('pages.total') > 1)
{
$html .= JText::sprintf('JLIB_HTML_PAGE_CURRENT_OF_TOTAL', $this->get('pages.current'), $this->get('pages.total'));
}
return $html;
}
/**
* Create and return the pagination result set counter string, e.g. Results 1-10 of 42
*
* @return string Pagination result set counter string.
*
* @since 11.1
*/
public function getResultsCounter()
{
// Initialise variables.
$html = null;
$fromResult = $this->limitstart + 1;
// If the limit is reached before the end of the list.
if ($this->limitstart + $this->limit < $this->total)
{
$toResult = $this->limitstart + $this->limit;
}
else
{
$toResult = $this->total;
}
// If there are results found.
if ($this->total > 0)
{
$msg = JText::sprintf('JLIB_HTML_RESULTS_OF', $fromResult, $toResult, $this->total);
$html .= "\n" . $msg;
}
else
{
$html .= "\n" . JText::_('JLIB_HTML_NO_RECORDS_FOUND');
}
return $html;
}
/**
* Create and return the pagination page list string, ie. Previous, Next, 1 2 3 ... x.
*
* @return string Pagination page list string.
*
* @since 11.1
*/
public function getPagesLinks()
{
$app = JFactory::getApplication();
// Build the page navigation list.
$data = $this->_buildDataObject();
$list = array();
$list['prefix'] = $this->prefix;
$itemOverride = false;
$listOverride = false;
// T3: detect if chrome pagination.php in template or in plugin
$chromePath = T3Path::getPath ('html/pagination.php');
// $chromePath = JPATH_THEMES . '/' . $app->getTemplate() . '/html/pagination.php';
if (file_exists($chromePath))
{
include_once $chromePath;
if (function_exists('pagination_item_active') && function_exists('pagination_item_inactive'))
{
$itemOverride = true;
}
if (function_exists('pagination_list_render'))
{
$listOverride = true;
}
}
// Build the select list
if ($data->all->base !== null)
{
$list['all']['active'] = true;
$list['all']['data'] = ($itemOverride) ? pagination_item_active($data->all) : $this->_item_active($data->all);
}
else
{
$list['all']['active'] = false;
$list['all']['data'] = ($itemOverride) ? pagination_item_inactive($data->all) : $this->_item_inactive($data->all);
}
if ($data->start->base !== null)
{
$list['start']['active'] = true;
$list['start']['data'] = ($itemOverride) ? pagination_item_active($data->start) : $this->_item_active($data->start);
}
else
{
$list['start']['active'] = false;
$list['start']['data'] = ($itemOverride) ? pagination_item_inactive($data->start) : $this->_item_inactive($data->start);
}
if ($data->previous->base !== null)
{
$list['previous']['active'] = true;
$list['previous']['data'] = ($itemOverride) ? pagination_item_active($data->previous) : $this->_item_active($data->previous);
}
else
{
$list['previous']['active'] = false;
$list['previous']['data'] = ($itemOverride) ? pagination_item_inactive($data->previous) : $this->_item_inactive($data->previous);
}
$list['pages'] = array(); //make sure it exists
foreach ($data->pages as $i => $page)
{
if ($page->base !== null)
{
$list['pages'][$i]['active'] = true;
$list['pages'][$i]['data'] = ($itemOverride) ? pagination_item_active($page) : $this->_item_active($page);
}
else
{
$list['pages'][$i]['active'] = false;
$list['pages'][$i]['data'] = ($itemOverride) ? pagination_item_inactive($page) : $this->_item_inactive($page);
}
}
if ($data->next->base !== null)
{
$list['next']['active'] = true;
$list['next']['data'] = ($itemOverride) ? pagination_item_active($data->next) : $this->_item_active($data->next);
}
else
{
$list['next']['active'] = false;
$list['next']['data'] = ($itemOverride) ? pagination_item_inactive($data->next) : $this->_item_inactive($data->next);
}
if ($data->end->base !== null)
{
$list['end']['active'] = true;
$list['end']['data'] = ($itemOverride) ? pagination_item_active($data->end) : $this->_item_active($data->end);
}
else
{
$list['end']['active'] = false;
$list['end']['data'] = ($itemOverride) ? pagination_item_inactive($data->end) : $this->_item_inactive($data->end);
}
if ($this->total > $this->limit)
{
return ($listOverride) ? pagination_list_render($list) : $this->_list_render($list);
}
else
{
return '';
}
}
/**
* Return the pagination footer.
*
* @return string Pagination footer.
*
* @since 11.1
*/
public function getListFooter()
{
$app = JFactory::getApplication();
$list = array();
$list['prefix'] = $this->prefix;
$list['limit'] = $this->limit;
$list['limitstart'] = $this->limitstart;
$list['total'] = $this->total;
$list['limitfield'] = $this->getLimitBox();
$list['pagescounter'] = $this->getPagesCounter();
$list['pageslinks'] = $this->getPagesLinks();
// T3: detect if chrome pagination.php in template or in plugin
$chromePath = T3Path::getPath ('html/pagination.php');
// $chromePath = JPATH_THEMES . '/' . $app->getTemplate() . '/html/pagination.php';
if (file_exists($chromePath))
{
include_once $chromePath;
if (function_exists('pagination_list_footer'))
{
return pagination_list_footer($list);
}
}
return $this->_list_footer($list);
}
/**
* Creates a dropdown box for selecting how many records to show per page.
*
* @return string The HTML for the limit # input box.
*
* @since 11.1
*/
public function getLimitBox()
{
$app = JFactory::getApplication();
// Initialise variables.
$limits = array();
// Make the option list.
for ($i = 5; $i <= 30; $i += 5)
{
$limits[] = JHtml::_('select.option', "$i");
}
$limits[] = JHtml::_('select.option', '50', JText::_('J50'));
$limits[] = JHtml::_('select.option', '100', JText::_('J100'));
$limits[] = JHtml::_('select.option', '0', JText::_('JALL'));
$selected = $this->_viewall ? 0 : $this->limit;
// Build the select list.
if (T3::isAdmin())
{
$html = JHtml::_(
'select.genericlist',
$limits,
$this->prefix . 'limit',
'class="inputbox" size="1" onchange="Joomla.submitform();"',
'value',
'text',
$selected
);
}
else
{
$html = JHtml::_(
'select.genericlist',
$limits,
$this->prefix . 'limit',
'class="inputbox" size="1" onchange="this.form.submit()"',
'value',
'text',
$selected
);
}
return $html;
}
/**
* Return the icon to move an item UP.
*
* @param integer $i The row index.
* @param boolean $condition True to show the icon.
* @param string $task The task to fire.
* @param string $alt The image alternative text string.
* @param boolean $enabled An optional setting for access control on the action.
* @param string $checkbox An optional prefix for checkboxes.
*
* @return string Either the icon to move an item up or a space.
*
* @since 11.1
*/
public function orderUpIcon($i, $condition = true, $task = 'orderup', $alt = 'JLIB_HTML_MOVE_UP', $enabled = true, $checkbox = 'cb')
{
if (($i > 0 || ($i + $this->limitstart > 0)) && $condition)
{
return JHtml::_('jgrid.orderUp', $i, $task, '', $alt, $enabled, $checkbox);
}
else
{
return ' ';
}
}
/**
* Return the icon to move an item DOWN.
*
* @param integer $i The row index.
* @param integer $n The number of items in the list.
* @param boolean $condition True to show the icon.
* @param string $task The task to fire.
* @param string $alt The image alternative text string.
* @param boolean $enabled An optional setting for access control on the action.
* @param string $checkbox An optional prefix for checkboxes.
*
* @return string Either the icon to move an item down or a space.
*
* @since 11.1
*/
public function orderDownIcon($i, $n, $condition = true, $task = 'orderdown', $alt = 'JLIB_HTML_MOVE_DOWN', $enabled = true, $checkbox = 'cb')
{
if (($i < $n - 1 || $i + $this->limitstart < $this->total - 1) && $condition)
{
return JHtml::_('jgrid.orderDown', $i, $task, '', $alt, $enabled, $checkbox);
}
else
{
return ' ';
}
}
/**
* Create the HTML for a list footer
*
* @param array $list Pagination list data structure.
*
* @return string HTML for a list footer
*
* @since 11.1
*/
protected function _list_footer($list)
{
$html = "<div class=\"list-footer\">\n";
$html .= "\n<div class=\"limit\">" . JText::_('JGLOBAL_DISPLAY_NUM') . $list['limitfield'] . "</div>";
$html .= $list['pageslinks'];
$html .= "\n<div class=\"counter\">" . $list['pagescounter'] . "</div>";
$html .= "\n<input type=\"hidden\" name=\"" . $list['prefix'] . "limitstart\" value=\"" . $list['limitstart'] . "\" />";
$html .= "\n</div>";
return $html;
}
/**
* Create the html for a list footer
*
* @param array $list Pagination list data structure.
*
* @return string HTML for a list start, previous, next,end
*
* @since 11.1
*/
protected function _list_render($list)
{
// Reverse output rendering for right-to-left display.
$html = '<ul>';
$html .= '<li class="pagination-start">' . $list['start']['data'] . '</li>';
$html .= '<li class="pagination-prev">' . $list['previous']['data'] . '</li>';
foreach ($list['pages'] as $page)
{
$html .= '<li>' . $page['data'] . '</li>';
}
$html .= '<li class="pagination-next">' . $list['next']['data'] . '</li>';
$html .= '<li class="pagination-end">' . $list['end']['data'] . '</li>';
$html .= '</ul>';
return $html;
}
/**
* Method to create an active pagination link to the item
*
* @param JPaginationObject &$item The object with which to make an active link.
*
* @return string HTML link
*
* @since 11.1
*/
protected function _item_active(&$item)
{
$app = JFactory::getApplication();
if (T3::isAdmin())
{
if ($item->base > 0)
{
return "<a title=\"" . $item->text . "\" onclick=\"document.adminForm." . $this->prefix . "limitstart.value=" . $item->base
. "; Joomla.submitform();return false;\">" . $item->text . "</a>";
}
else
{
return "<a title=\"" . $item->text . "\" onclick=\"document.adminForm." . $this->prefix
. "limitstart.value=0; Joomla.submitform();return false;\">" . $item->text . "</a>";
}
}
else
{
return "<a title=\"" . $item->text . "\" href=\"" . $item->link . "\" class=\"pagenav\">" . $item->text . "</a>";
}
}
/**
* Method to create an inactive pagination string
*
* @param object &$item The item to be processed
*
* @return string
*
* @since 11.1
*/
protected function _item_inactive(&$item)
{
$app = JFactory::getApplication();
if (T3::isAdmin())
{
return "<span>" . $item->text . "</span>";
}
else
{
return "<span class=\"pagenav\">" . $item->text . "</span>";
}
}
/**
* Create and return the pagination data object.
*
* @return object Pagination data object.
*
* @since 11.1
*/
protected function _buildDataObject()
{
// Initialise variables.
$data = new stdClass;
// Build the additional URL parameters string.
$params = '';
if (!empty($this->_additionalUrlParams))
{
foreach ($this->_additionalUrlParams as $key => $value)
{
$params .= '&' . $key . '=' . $value;
}
}
$data->all = new JPaginationObject(JText::_('JLIB_HTML_VIEW_ALL'), $this->prefix);
if (!$this->_viewall)
{
$data->all->base = '0';
$data->all->link = JRoute::_($params . '&' . $this->prefix . 'limitstart=');
}
// Set the start and previous data objects.
$data->start = new JPaginationObject(JText::_('JLIB_HTML_START'), $this->prefix);
$data->previous = new JPaginationObject(JText::_('JPREV'), $this->prefix);
if ($this->get('pages.current') > 1)
{
$page = ($this->get('pages.current') - 2) * $this->limit;
// Set the empty for removal from route
//$page = $page == 0 ? '' : $page;
$data->start->base = '0';
$data->start->link = JRoute::_($params . '&' . $this->prefix . 'limitstart=0' . '&limit=' . $this->limit);
$data->previous->base = $page;
$data->previous->link = JRoute::_($params . '&' . $this->prefix . 'limitstart=' . $page . '&limit=' . $this->limit);
}
// Set the next and end data objects.
$data->next = new JPaginationObject(JText::_('JNEXT'), $this->prefix);
$data->end = new JPaginationObject(JText::_('JLIB_HTML_END'), $this->prefix);
if ($this->get('pages.current') < $this->get('pages.total'))
{
$next = $this->get('pages.current') * $this->limit;
$end = ($this->get('pages.total') - 1) * $this->limit;
$data->next->base = $next;
$data->next->link = JRoute::_($params . '&' . $this->prefix . 'limitstart=' . $next . '&limit=' . $this->limit);
$data->end->base = $end;
$data->end->link = JRoute::_($params . '&' . $this->prefix . 'limitstart=' . $end . '&limit=' . $this->limit);
}
$data->pages = array();
$stop = $this->get('pages.stop');
for ($i = $this->get('pages.start'); $i <= $stop; $i++)
{
$offset = ($i - 1) * $this->limit;
// Set the empty for removal from route
//$offset = $offset == 0 ? '' : $offset;
$data->pages[$i] = new JPaginationObject($i, $this->prefix);
if ($i != $this->get('pages.current') || $this->_viewall)
{
$data->pages[$i]->base = $offset;
$data->pages[$i]->link = JRoute::_($params . '&' . $this->prefix . 'limitstart=' . $offset . '&limit=' . $this->limit);
}
}
return $data;
}
}
/**
* Pagination object representing a particular item in the pagination lists.
*
* @package Joomla.Platform
* @subpackage HTML
* @since 11.1
*/
class JPaginationObject extends JObject
{
/**
* @var string The link text.
* @since 11.1
*/
public $text;
/**
* @var integer The number of rows as a base offset.
* @since 11.1
*/
public $base;
/**
* @var string The link URL.
* @since 11.1
*/
public $link;
/**
* @var integer The prefix used for request variables.
* @since 11.1
*/
public $prefix;
/**
* 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.
*
* @since 11.1
*/
public function __construct($text, $prefix = '', $base = null, $link = null)
{
$this->text = $text;
$this->prefix = $prefix;
$this->base = $base;
$this->link = $link;
}
}