/**
  * Class constructor
  *
  * @param   array  $options  Associative array of options
  *
  * @since  11.1
  */
 public function __construct($options = array())
 {
     parent::__construct($options);
     // Set document type
     $this->_type = 'opensearch';
     // Set mime type
     $this->_mime = 'application/opensearchdescription+xml';
     // Add the URL for self updating
     $update = new Opensearch\Url();
     $update->type = 'application/opensearchdescription+xml';
     $update->rel = 'self';
     $update->template = Route::_(Uri::getInstance());
     $this->addUrl($update);
     // Add the favicon as the default image
     // Try to find a favicon by checking the template and root folder
     $app = Factory::getApplication();
     $dirs = array(JPATH_THEMES . '/' . $app->getTemplate(), JPATH_BASE);
     foreach ($dirs as $dir) {
         if (file_exists($dir . '/favicon.ico')) {
             $path = str_replace(JPATH_BASE . '/', '', $dir);
             $path = str_replace('\\', '/', $path);
             $favicon = new Opensearch\Image();
             $favicon->data = Uri::base() . $path . '/favicon.ico';
             $favicon->height = '16';
             $favicon->width = '16';
             $favicon->type = 'image/vnd.microsoft.icon';
             $this->addImage($favicon);
             break;
         }
     }
 }
 /**
  * Constructor.
  *
  * @param   Registry  $options      JOAuth2Client options object
  * @param   Http      $http         The HTTP client object
  * @param   Input     $input        The input object
  * @param   Web       $application  The application object
  *
  * @since   12.3
  */
 public function __construct(Registry $options = null, Http $http = null, Input $input = null, Web $application = null)
 {
     $this->options = isset($options) ? $options : new Registry();
     $this->http = isset($http) ? $http : new Http($this->options);
     $this->input = isset($input) ? $input : Factory::getApplication()->input;
     $this->application = isset($application) ? $application : new Web();
 }
 /**
  * Get and prepare system message data for output
  *
  * @return  array  An array contains system message
  *
  * @since   12.2
  */
 private function getData()
 {
     // Initialise variables.
     $lists = array();
     // Get the message queue
     $messages = Factory::getApplication()->getMessageQueue();
     // Build the sorted message list
     if (is_array($messages) && !empty($messages)) {
         foreach ($messages as $msg) {
             if (isset($msg['type']) && isset($msg['message'])) {
                 $lists[$msg['type']][] = $msg['message'];
             }
         }
     }
     return $lists;
 }
 /**
  * Translates an internal Joomla URL to a humanly readible URL.
  *
  * @param   string   $url    Absolute or Relative URI to Joomla resource.
  * @param   boolean  $xhtml  Replace & by & for XML compilance.
  * @param   integer  $ssl    Secure state for the resolved URI.
  *                             1: Make URI secure using global secure site URI.
  *                             2: Make URI unsecure using the global unsecure site URI.
  *
  * @return  The translated humanly readible URL.
  *
  * @since   11.1
  */
 public static function _($url, $xhtml = true, $ssl = null)
 {
     if (!self::$_router) {
         // Get the router.
         self::$_router = Factory::getApplication()->getRouter();
         // Make sure that we have our router
         if (!self::$_router) {
             return null;
         }
     }
     if (strpos($url, '&') !== 0 && strpos($url, 'index.php') !== 0) {
         return $url;
     }
     // Build route.
     $uri = self::$_router->build($url);
     $url = $uri->toString(array('path', 'query', 'fragment'));
     // Replace spaces.
     $url = preg_replace('/\\s/u', '%20', $url);
     /*
      * Get the secure/unsecure URLs.
      *
      * If the first 5 characters of the BASE are 'https', then we are on an ssl connection over
      * https and need to set our secure URL to the current request URL, if not, and the scheme is
      * 'http', then we need to do a quick string manipulation to switch schemes.
      */
     if ((int) $ssl) {
         $uri = Uri::getInstance();
         // Get additional parts.
         static $prefix;
         if (!$prefix) {
             $prefix = $uri->toString(array('host', 'port'));
         }
         // Determine which scheme we want.
         $scheme = (int) $ssl === 1 ? 'https' : 'http';
         // Make sure our URL path begins with a slash.
         if (!preg_match('#^/#', $url)) {
             $url = '/' . $url;
         }
         // Build the URL.
         $url = $scheme . '://' . $prefix . $url;
     }
     if ($xhtml) {
         $url = htmlspecialchars($url);
     }
     return $url;
 }
 /**
  * Render the document.
  *
  * @param   boolean  $cache   If true, cache the output
  * @param   array    $params  Associative array of attributes
  *
  * @return  The rendered data
  *
  * @since   12.1
  */
 public function render($cache = false, $params = array())
 {
     // Get the image type
     $type = Factory::getApplication()->input->get('type', 'png');
     switch ($type) {
         case 'jpg':
         case 'jpeg':
             $this->_mime = 'image/jpeg';
             break;
         case 'gif':
             $this->_mime = 'image/gif';
             break;
         case 'png':
         default:
             $this->_mime = 'image/png';
             break;
     }
     $this->_charset = null;
     parent::render();
     return $this->getBuffer();
 }
 /**
  * Load the JavaScript behavior.
  *
  * @param   string  $group   The pane identifier.
  * @param   array   $params  Array of options.
  *
  * @return  void
  *
  * @since   11.1
  */
 protected static function _loadBehavior($group, $params = array())
 {
     static $loaded = array();
     if (!array_key_exists($group, $loaded)) {
         // Get the JInput object
         $input = Factory::getApplication()->input;
         $loaded[$group] = true;
         // Include mootools framework.
         Html::_('behavior.framework', true);
         $document = Factory::getDocument();
         $display = isset($params['startOffset']) && isset($params['startTransition']) && $params['startTransition'] ? (int) $params['startOffset'] : null;
         $show = isset($params['startOffset']) && !(isset($params['startTransition']) && $params['startTransition']) ? (int) $params['startOffset'] : null;
         $opt['onActive'] = "\\function(toggler, i) {toggler.addClass('pane-toggler-down');" . "toggler.removeClass('pane-toggler');i.addClass('pane-down');i.removeClass('pane-hide');Cookie.write('jpanesliders_" . $group . "',\$\$('div#" . $group . ".pane-sliders > .panel > h3').indexOf(toggler));}";
         $opt['onBackground'] = "\\function(toggler, i) {toggler.addClass('pane-toggler');" . "toggler.removeClass('pane-toggler-down');i.addClass('pane-hide');i.removeClass('pane-down');if(\$\$('div#" . $group . ".pane-sliders > .panel > h3').length==\$\$('div#" . $group . ".pane-sliders > .panel > h3.pane-toggler').length) Cookie.write('jpanesliders_" . $group . "',-1);}";
         $opt['duration'] = isset($params['duration']) ? (int) $params['duration'] : 300;
         $opt['display'] = isset($params['useCookie']) && $params['useCookie'] ? $input->cookie->get('jpanesliders_' . $group, $display, 'integer') : $display;
         $opt['show'] = isset($params['useCookie']) && $params['useCookie'] ? $input->cookie->get('jpanesliders_' . $group, $show, 'integer') : $show;
         $opt['opacity'] = isset($params['opacityTransition']) && $params['opacityTransition'] ? 'true' : 'false';
         $opt['alwaysHide'] = isset($params['allowAllClose']) && !$params['allowAllClose'] ? 'false' : 'true';
         $options = Html::getJSObject($opt);
         $js = "window.addEvent('domready', function(){ new Fx.Accordion(\$\$('div#" . $group . ".pane-sliders > .panel > h3.pane-toggler'), \$\$('div#" . $group . ".pane-sliders > .panel > div.pane-slider'), " . $options . "); });";
         $document->addScriptDeclaration($js);
     }
 }
 /**
  * Get the path to a layout from a Plugin
  *
  * @param   string  $type    Plugin type
  * @param   string  $name    Plugin name
  * @param   string  $layout  Layout name
  *
  * @return  string  Layout path
  *
  * @since   12.2
  */
 public static function getLayoutPath($type, $name, $layout = 'default')
 {
     $template = Factory::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/plg_' . $type . '_' . $name . '/' . $layout . '.php';
     $bPath = JPATH_BASE . '/plugins/' . $type . '/' . $name . '/tmpl/' . $defaultLayout . '.php';
     $dPath = JPATH_BASE . '/plugins/' . $type . '/' . $name . '/tmpl/' . 'default.php';
     // If the template has a layout override use it
     if (file_exists($tPath)) {
         return $tPath;
     } elseif (file_exists($bPath)) {
         return $bPath;
     } else {
         return $dPath;
     }
 }
 /**
  * Count the number of child menu items
  *
  * @return  integer  Number of child menu items
  *
  * @since   11.1
  */
 public function countMenuChildren()
 {
     static $children;
     if (!isset($children)) {
         $dbo = Factory::getDbo();
         $app = Factory::getApplication();
         $menu = $app->getMenu();
         $active = $menu->getActive();
         if ($active) {
             $query = $dbo->getQuery(true);
             $query->select('COUNT(*)');
             $query->from('#__menu');
             $query->where('parent_id = ' . $active->id);
             $query->where('published = 1');
             $children = $dbo->loadResult();
         } else {
             $children = 0;
         }
     }
     return $children;
 }
 /**
  * Determine whether input fields for client settings need to be shown
  *
  * If valid credentials were passed along with the request, they are saved to the session.
  * This functions returns an exception if invalid credentials have been given or if the
  * connection to the server failed for some other reason.
  *
  * @param   string  $client  The name of the client.
  *
  * @return  mixed  True, if FTP settings; JError if using legacy tree.
  *
  * @since   11.1
  * @throws  InvalidArgumentException if credentials invalid
  */
 public static function setCredentialsFromRequest($client)
 {
     // Determine whether FTP credentials have been passed along with the current request
     $input = Factory::getApplication()->input;
     $user = $input->post->getString('username', null);
     $pass = $input->post->getString('password', null);
     if ($user != '' && $pass != '') {
         // Add credentials to the session
         if (self::setCredentials($client, $user, $pass)) {
             $return = false;
         } else {
             if (class_exists('\\JError')) {
                 $return = JError::raiseWarning('SOME_ERROR_CODE', JText::_('JLIB_CLIENT_ERROR_HELPER_SETCREDENTIALSFROMREQUEST_FAILED'));
             } else {
                 throw new InvalidArgumentException('Invalid user credentials');
             }
         }
     } else {
         // Just determine if the FTP input fields need to be shown
         $return = !self::hasCredentials('ftp');
     }
     return $return;
 }
 /**
  * Method to get the field input markup for Access Control Lists.
  * Optionally can be associated with a specific component and section.
  *
  * TODO: Add access check.
  *
  * @return  string  The field input markup.
  *
  * @since   11.1
  */
 protected function getInput()
 {
     Html::_('behavior.tooltip');
     // Initialise some field attributes.
     $section = $this->element['section'] ? (string) $this->element['section'] : '';
     $component = $this->element['component'] ? (string) $this->element['component'] : '';
     $assetField = $this->element['asset_field'] ? (string) $this->element['asset_field'] : 'asset_id';
     // Get the actions for the asset.
     $actions = Access::getActionsFromFile(JPATH_ADMINISTRATOR . '/components/' . $component . '/access.xml', "/access/section[@name='" . $section . "']/");
     // Iterate over the children and add to the actions.
     foreach ($this->element->children() as $el) {
         if ($el->getName() == 'action') {
             $actions[] = (object) array('name' => (string) $el['name'], 'title' => (string) $el['title'], 'description' => (string) $el['description']);
         }
     }
     // Get the explicit rules for this asset.
     if ($section == 'component') {
         // Need to find the asset id by the name of the component.
         $db = Factory::getDbo();
         $query = $db->getQuery(true);
         $query->select($db->quoteName('id'));
         $query->from($db->quoteName('#__assets'));
         $query->where($db->quoteName('name') . ' = ' . $db->quote($component));
         $db->setQuery($query);
         $assetId = (int) $db->loadResult();
     } else {
         // Find the asset id of the content.
         // Note that for global configuration, com_config injects asset_id = 1 into the form.
         $assetId = $this->form->getValue($assetField);
     }
     // Use the compact form for the content rules (deprecated).
     /* @todo remove code:
     		if (!empty($component) && $section != 'component') {
     			return Html::_('rules.assetFormWidget', $actions, $assetId, $assetId ? null : $component, $this->name, $this->id);
     		}
     		 */
     // Full width format.
     // Get the rules for just this asset (non-recursive).
     $assetRules = Access::getAssetRules($assetId);
     // Get the available user groups.
     $groups = $this->getUserGroups();
     // Build the form control.
     $curLevel = 0;
     // Prepare output
     $html = array();
     $html[] = '<div id="permissions-sliders" class="pane-sliders">';
     $html[] = '<p class="rule-desc">' . Text::_('JLIB_RULES_SETTINGS_DESC') . '</p>';
     $html[] = '<ul id="rules">';
     // Start a row for each user group.
     foreach ($groups as $group) {
         $difLevel = $group->level - $curLevel;
         if ($difLevel > 0) {
             $html[] = '<li><ul>';
         } elseif ($difLevel < 0) {
             $html[] = str_repeat('</ul></li>', -$difLevel);
         }
         $html[] = '<li>';
         $html[] = '<div class="panel">';
         $html[] = '<h3 class="pane-toggler title"><a href="javascript:void(0);"><span>';
         $html[] = str_repeat('<span class="level">|&ndash;</span> ', $curLevel = $group->level) . $group->text;
         $html[] = '</span></a></h3>';
         $html[] = '<div class="pane-slider content pane-hide">';
         $html[] = '<div class="mypanel">';
         $html[] = '<table class="group-rules">';
         $html[] = '<thead>';
         $html[] = '<tr>';
         $html[] = '<th class="actions" id="actions-th' . $group->value . '">';
         $html[] = '<span class="acl-action">' . Text::_('JLIB_RULES_ACTION') . '</span>';
         $html[] = '</th>';
         $html[] = '<th class="settings" id="settings-th' . $group->value . '">';
         $html[] = '<span class="acl-action">' . Text::_('JLIB_RULES_SELECT_SETTING') . '</span>';
         $html[] = '</th>';
         // The calculated setting is not shown for the root group of global configuration.
         $canCalculateSettings = $group->parent_id || !empty($component);
         if ($canCalculateSettings) {
             $html[] = '<th id="aclactionth' . $group->value . '">';
             $html[] = '<span class="acl-action">' . Text::_('JLIB_RULES_CALCULATED_SETTING') . '</span>';
             $html[] = '</th>';
         }
         $html[] = '</tr>';
         $html[] = '</thead>';
         $html[] = '<tbody>';
         foreach ($actions as $action) {
             $html[] = '<tr>';
             $html[] = '<td headers="actions-th' . $group->value . '">';
             $html[] = '<label class="hasTip" for="' . $this->id . '_' . $action->name . '_' . $group->value . '" title="' . htmlspecialchars(Text::_($action->title) . '::' . Text::_($action->description), ENT_COMPAT, 'UTF-8') . '">';
             $html[] = Text::_($action->title);
             $html[] = '</label>';
             $html[] = '</td>';
             $html[] = '<td headers="settings-th' . $group->value . '">';
             $html[] = '<select name="' . $this->name . '[' . $action->name . '][' . $group->value . ']" id="' . $this->id . '_' . $action->name . '_' . $group->value . '" title="' . Text::sprintf('JLIB_RULES_SELECT_ALLOW_DENY_GROUP', Text::_($action->title), trim($group->text)) . '">';
             $inheritedRule = Access::checkGroup($group->value, $action->name, $assetId);
             // Get the actual setting for the action for this group.
             $assetRule = $assetRules->allow($action->name, $group->value);
             // Build the dropdowns for the permissions sliders
             // The parent group has "Not Set", all children can rightly "Inherit" from that.
             $html[] = '<option value=""' . ($assetRule === null ? ' selected="selected"' : '') . '>' . Text::_(empty($group->parent_id) && empty($component) ? 'JLIB_RULES_NOT_SET' : 'JLIB_RULES_INHERITED') . '</option>';
             $html[] = '<option value="1"' . ($assetRule === true ? ' selected="selected"' : '') . '>' . Text::_('JLIB_RULES_ALLOWED') . '</option>';
             $html[] = '<option value="0"' . ($assetRule === false ? ' selected="selected"' : '') . '>' . Text::_('JLIB_RULES_DENIED') . '</option>';
             $html[] = '</select>&#160; ';
             // If this asset's rule is allowed, but the inherited rule is deny, we have a conflict.
             if ($assetRule === true && $inheritedRule === false) {
                 $html[] = Text::_('JLIB_RULES_CONFLICT');
             }
             $html[] = '</td>';
             // Build the Calculated Settings column.
             // The inherited settings column is not displayed for the root group in global configuration.
             if ($canCalculateSettings) {
                 $html[] = '<td headers="aclactionth' . $group->value . '">';
                 // This is where we show the current effective settings considering currrent group, path and cascade.
                 // Check whether this is a component or global. Change the text slightly.
                 if (Access::checkGroup($group->value, 'core.admin') !== true) {
                     if ($inheritedRule === null) {
                         $html[] = '<span class="icon-16-unset">' . Text::_('JLIB_RULES_NOT_ALLOWED') . '</span>';
                     } elseif ($inheritedRule === true) {
                         $html[] = '<span class="icon-16-allowed">' . Text::_('JLIB_RULES_ALLOWED') . '</span>';
                     } elseif ($inheritedRule === false) {
                         if ($assetRule === false) {
                             $html[] = '<span class="icon-16-denied">' . Text::_('JLIB_RULES_NOT_ALLOWED') . '</span>';
                         } else {
                             $html[] = '<span class="icon-16-denied"><span class="icon-16-locked">' . Text::_('JLIB_RULES_NOT_ALLOWED_LOCKED') . '</span></span>';
                         }
                     }
                 } elseif (!empty($component)) {
                     $html[] = '<span class="icon-16-allowed"><span class="icon-16-locked">' . Text::_('JLIB_RULES_ALLOWED_ADMIN') . '</span></span>';
                 } else {
                     // Special handling for  groups that have global admin because they can't  be denied.
                     // The admin rights can be changed.
                     if ($action->name === 'core.admin') {
                         $html[] = '<span class="icon-16-allowed">' . Text::_('JLIB_RULES_ALLOWED') . '</span>';
                     } elseif ($inheritedRule === false) {
                         // Other actions cannot be changed.
                         $html[] = '<span class="icon-16-denied"><span class="icon-16-locked">' . Text::_('JLIB_RULES_NOT_ALLOWED_ADMIN_CONFLICT') . '</span></span>';
                     } else {
                         $html[] = '<span class="icon-16-allowed"><span class="icon-16-locked">' . Text::_('JLIB_RULES_ALLOWED_ADMIN') . '</span></span>';
                     }
                 }
                 $html[] = '</td>';
             }
             $html[] = '</tr>';
         }
         $html[] = '</tbody>';
         $html[] = '</table></div>';
         $html[] = '</div></div>';
         $html[] = '</li>';
     }
     $html[] = str_repeat('</ul></li>', $curLevel);
     $html[] = '</ul><div class="rule-notes">';
     if ($section == 'component' || $section == null) {
         $html[] = Text::_('JLIB_RULES_SETTING_NOTES');
     } else {
         $html[] = Text::_('JLIB_RULES_SETTING_NOTES_ITEM');
     }
     $html[] = '</div></div>';
     // Get the JInput object
     $input = Factory::getApplication()->input;
     $js = "window.addEvent('domready', function(){ new Fx.Accordion(\$\$('div#permissions-sliders.pane-sliders .panel h3.pane-toggler')," . "\$\$('div#permissions-sliders.pane-sliders .panel div.pane-slider'), {onActive: function(toggler, i) {toggler.addClass('pane-toggler-down');" . "toggler.removeClass('pane-toggler');i.addClass('pane-down');i.removeClass('pane-hide');Cookie.write('jpanesliders_permissions-sliders" . $component . "',\$\$('div#permissions-sliders.pane-sliders .panel h3').indexOf(toggler));}," . "onBackground: function(toggler, i) {toggler.addClass('pane-toggler');toggler.removeClass('pane-toggler-down');i.addClass('pane-hide');" . "i.removeClass('pane-down');}, duration: 300, display: " . $input->cookie->get('jpanesliders_permissions-sliders' . $component, 0, 'integer') . ", show: " . $input->cookie->get('jpanesliders_permissions-sliders' . $component, 0, 'integer') . ", alwaysHide:true, opacity: false}); });";
     Factory::getDocument()->addScriptDeclaration($js);
     return implode("\n", $html);
 }
 /**
  * Create safe id for cached data from url parameters set by plugins and framework
  *
  * @return  string   md5 encoded cacheid
  *
  * @since   11.1
  */
 public static function makeId()
 {
     $app = Factory::getApplication();
     // Get url parameters set by plugins
     $registeredurlparams = $app->registeredurlparams;
     // Platform defaults
     $registeredurlparams->format = 'WORD';
     $registeredurlparams->option = 'WORD';
     $registeredurlparams->view = 'WORD';
     $registeredurlparams->layout = 'WORD';
     $registeredurlparams->tpl = 'CMD';
     $registeredurlparams->id = 'INT';
     $safeuriaddon = new stdClass();
     foreach ($registeredurlparams as $key => $value) {
         $safeuriaddon->{$key} = $app->input->get($key, null, $value);
     }
     return md5(serialize($safeuriaddon));
 }
 /**
  * Checks for a form token in the request.
  *
  * Use in conjunction with JHtml::_('form.token') or JSession::getFormToken.
  *
  * @param   string  $method  The request method in which to look for the token key.
  *
  * @return  boolean  True if found and valid, false otherwise.
  *
  * @since   12.1
  */
 public static function checkToken($method = 'post')
 {
     $token = self::getFormToken();
     $app = Factory::getApplication();
     if (!$app->input->{$method}->get($token, '', 'alnum')) {
         $session = Factory::getSession();
         if ($session->isNew()) {
             // Redirect to login screen.
             $app->redirect(Route::_('index.php'), Text::_('JLIB_ENVIRONMENT_SESSION_EXPIRED'));
             $app->close();
         } else {
             return false;
         }
     } else {
         return true;
     }
 }
 /**
  * Compute the files to be included
  *
  * @param   string   $folder          folder name to search into (images, css, js, ...)
  * @param   string   $file            path to file
  * @param   boolean  $relative        path to file is relative to /media folder
  * @param   boolean  $detect_browser  detect browser to include specific browser files
  * @param   boolean  $detect_debug    detect debug to include compressed files if debug is on
  *
  * @return  array    files to be included
  *
  * @see     JBrowser
  * @since   11.1
  */
 protected static function includeRelativeFiles($folder, $file, $relative, $detect_browser, $detect_debug)
 {
     // If http is present in filename
     if (strpos($file, 'http') === 0) {
         $includes = array($file);
     } else {
         // Extract extension and strip the file
         $strip = File::stripExt($file);
         $ext = File::getExt($file);
         // Prepare array of files
         $includes = array();
         // Detect browser and compute potential files
         if ($detect_browser) {
             $navigator = Browser::getInstance();
             $browser = $navigator->getBrowser();
             $major = $navigator->getMajor();
             $minor = $navigator->getMinor();
             // Try to include files named filename.ext, filename_browser.ext, filename_browser_major.ext, filename_browser_major_minor.ext
             // where major and minor are the browser version names
             $potential = array($strip, $strip . '_' . $browser, $strip . '_' . $browser . '_' . $major, $strip . '_' . $browser . '_' . $major . '_' . $minor);
         } else {
             $potential = array($strip);
         }
         // If relative search in template directory or media directory
         if ($relative) {
             // Get the template
             $app = Factory::getApplication();
             $template = $app->getTemplate();
             // For each potential files
             foreach ($potential as $strip) {
                 $files = array();
                 // Detect debug mode
                 if ($detect_debug && Factory::getConfig()->get('debug')) {
                     /*
                      * Detect if we received a file in the format name.min.ext
                      * If so, strip the .min part out, otherwise append -uncompressed
                      */
                     if (strrpos($strip, '.min', '-4')) {
                         $position = strrpos($strip, '.min', '-4');
                         $filename = str_replace('.min', '.', $strip, $position);
                         $files[] = $filename . $ext;
                     } else {
                         $files[] = $strip . '-uncompressed.' . $ext;
                     }
                 }
                 $files[] = $strip . '.' . $ext;
                 /*
                  * Loop on 1 or 2 files and break on first found.
                  * Add the content of the MD5SUM file located in the same folder to url to ensure cache browser refresh
                  * This MD5SUM file must represent the signature of the folder content
                  */
                 foreach ($files as $file) {
                     // If the file is in the template folder
                     $path = JPATH_THEMES . "/{$template}/{$folder}/{$file}";
                     if (file_exists($path)) {
                         $md5 = dirname($path) . '/MD5SUM';
                         $includes[] = Uri::base(true) . "/templates/{$template}/{$folder}/{$file}" . (file_exists($md5) ? '?' . file_get_contents($md5) : '');
                         break;
                     } else {
                         // If the file contains any /: it can be in an media extension subfolder
                         if (strpos($file, '/')) {
                             // Divide the file extracting the extension as the first part before /
                             list($extension, $file) = explode('/', $file, 2);
                             // If the file yet contains any /: it can be a plugin
                             if (strpos($file, '/')) {
                                 // Divide the file extracting the element as the first part before /
                                 list($element, $file) = explode('/', $file, 2);
                                 // Try to deal with plugins group in the media folder
                                 $path = JPATH_ROOT . "/media/{$extension}/{$element}/{$folder}/{$file}";
                                 if (file_exists($path)) {
                                     $md5 = dirname($path) . '/MD5SUM';
                                     $includes[] = Uri::root(true) . "/media/{$extension}/{$element}/{$folder}/{$file}" . (file_exists($md5) ? '?' . file_get_contents($md5) : '');
                                     break;
                                 }
                                 // Try to deal with classical file in a a media subfolder called element
                                 $path = JPATH_ROOT . "/media/{$extension}/{$folder}/{$element}/{$file}";
                                 if (file_exists($path)) {
                                     $md5 = dirname($path) . '/MD5SUM';
                                     $includes[] = Uri::root(true) . "/media/{$extension}/{$folder}/{$element}/{$file}" . (file_exists($md5) ? '?' . file_get_contents($md5) : '');
                                     break;
                                 }
                                 // Try to deal with system files in the template folder
                                 $path = JPATH_THEMES . "/{$template}/{$folder}/system/{$element}/{$file}";
                                 if (file_exists($path)) {
                                     $md5 = dirname($path) . '/MD5SUM';
                                     $includes[] = Uri::root(true) . "/templates/{$template}/{$folder}/system/{$element}/{$file}" . (file_exists($md5) ? '?' . file_get_contents($md5) : '');
                                     break;
                                 }
                                 // Try to deal with system files in the media folder
                                 $path = JPATH_ROOT . "/media/system/{$folder}/{$element}/{$file}";
                                 if (file_exists($path)) {
                                     $md5 = dirname($path) . '/MD5SUM';
                                     $includes[] = Uri::root(true) . "/media/system/{$folder}/{$element}/{$file}" . (file_exists($md5) ? '?' . file_get_contents($md5) : '');
                                     break;
                                 }
                             } else {
                                 // Try to deals in the extension media folder
                                 $path = JPATH_ROOT . "/media/{$extension}/{$folder}/{$file}";
                                 if (file_exists($path)) {
                                     $md5 = dirname($path) . '/MD5SUM';
                                     $includes[] = Uri::root(true) . "/media/{$extension}/{$folder}/{$file}" . (file_exists($md5) ? '?' . file_get_contents($md5) : '');
                                     break;
                                 }
                                 // Try to deal with system files in the template folder
                                 $path = JPATH_THEMES . "/{$template}/{$folder}/system/{$file}";
                                 if (file_exists($path)) {
                                     $md5 = dirname($path) . '/MD5SUM';
                                     $includes[] = Uri::root(true) . "/templates/{$template}/{$folder}/system/{$file}" . (file_exists($md5) ? '?' . file_get_contents($md5) : '');
                                     break;
                                 }
                                 // Try to deal with system files in the media folder
                                 $path = JPATH_ROOT . "/media/system/{$folder}/{$file}";
                                 if (file_exists($path)) {
                                     $md5 = dirname($path) . '/MD5SUM';
                                     $includes[] = Uri::root(true) . "/media/system/{$folder}/{$file}" . (file_exists($md5) ? '?' . file_get_contents($md5) : '');
                                     break;
                                 }
                             }
                         } else {
                             $path = JPATH_ROOT . "/media/system/{$folder}/{$file}";
                             if (file_exists($path)) {
                                 $md5 = dirname($path) . '/MD5SUM';
                                 $includes[] = Uri::root(true) . "/media/system/{$folder}/{$file}" . (file_exists($md5) ? '?' . file_get_contents($md5) : '');
                                 break;
                             }
                         }
                     }
                 }
             }
         } else {
             foreach ($potential as $strip) {
                 $files = array();
                 // Detect debug mode
                 if ($detect_debug && Factory::getConfig()->get('debug')) {
                     $files[] = $strip . '-uncompressed.' . $ext;
                 }
                 $files[] = $strip . '.' . $ext;
                 /*
                  * Loop on 1 or 2 files and break on first found.
                  * Add the content of the MD5SUM file located in the same folder to url to ensure cache browser refresh
                  * This MD5SUM file must represent the signature of the folder content
                  */
                 foreach ($files as $file) {
                     $path = JPATH_ROOT . "/{$file}";
                     if (file_exists($path)) {
                         $md5 = dirname($path) . '/MD5SUM';
                         $includes[] = Uri::root(true) . "/{$file}" . (file_exists($md5) ? '?' . file_get_contents($md5) : '');
                         break;
                     }
                 }
             }
         }
     }
     return $includes;
 }
 /**
  * There is no change in page data so send an
  * unmodified header and die gracefully
  *
  * @return  void
  *
  * @since   11.1
  */
 protected function _noChange()
 {
     $app = Factory::getApplication();
     // Send not modified header and exit gracefully
     header('HTTP/1.x 304 Not Modified', true);
     $app->close();
 }
 /**
  * Method to create an inactive pagination string
  *
  * @param   Object  $item  The item to be processed
  *
  * @return  string
  *
  * @since   11.1
  */
 protected function _item_inactive(Object $item)
 {
     $app = Factory::getApplication();
     if ($app->isAdmin()) {
         return "<span>" . $item->text . "</span>";
     } else {
         return "<span class=\"pagenav\">" . $item->text . "</span>";
     }
 }
 /**
  * Generates the head HTML and return the results as a string
  *
  * @param   JDocument  $document  The document for which the head will be created
  *
  * @return  string  The head hTML
  *
  * @since   11.1
  */
 public function fetchHead(Document $document)
 {
     // Trigger the onBeforeCompileHead event (skip for installation, since it causes an error)
     $app = Factory::getApplication();
     $app->triggerEvent('onBeforeCompileHead');
     // Get line endings
     $lnEnd = $document->_getLineEnd();
     $tab = $document->_getTab();
     $tagEnd = ' />';
     $buffer = '';
     // Generate charset when using HTML5 (should happen first)
     if ($document->isHtml5()) {
         $buffer .= $tab . '<meta charset="' . $document->getCharset() . '" />' . $lnEnd;
     }
     // Generate base tag (need to happen early)
     $base = $document->getBase();
     if (!empty($base)) {
         $buffer .= $tab . '<base href="' . $document->getBase() . '" />' . $lnEnd;
     }
     // Generate META tags (needs to happen as early as possible in the head)
     foreach ($document->_metaTags as $type => $tag) {
         foreach ($tag as $name => $content) {
             if ($type == 'http-equiv' && !($document->isHtml5() && $name == 'content-type')) {
                 $buffer .= $tab . '<meta http-equiv="' . $name . '" content="' . htmlspecialchars($content) . '" />' . $lnEnd;
             } elseif ($type == 'standard' && !empty($content)) {
                 $buffer .= $tab . '<meta name="' . $name . '" content="' . htmlspecialchars($content) . '" />' . $lnEnd;
             }
         }
     }
     // Don't add empty descriptions
     $documentDescription = $document->getDescription();
     if ($documentDescription) {
         $buffer .= $tab . '<meta name="description" content="' . htmlspecialchars($documentDescription) . '" />' . $lnEnd;
     }
     // Don't add empty generators
     $generator = $document->getGenerator();
     if ($generator) {
         $buffer .= $tab . '<meta name="generator" content="' . htmlspecialchars($generator) . '" />' . $lnEnd;
     }
     $buffer .= $tab . '<title>' . htmlspecialchars($document->getTitle(), ENT_COMPAT, 'UTF-8') . '</title>' . $lnEnd;
     // Generate link declarations
     foreach ($document->_links as $link => $linkAtrr) {
         $buffer .= $tab . '<link href="' . $link . '" ' . $linkAtrr['relType'] . '="' . $linkAtrr['relation'] . '"';
         if ($temp = ArrayHelper::toString($linkAtrr['attribs'])) {
             $buffer .= ' ' . $temp;
         }
         $buffer .= ' />' . $lnEnd;
     }
     // Generate stylesheet links
     foreach ($document->_styleSheets as $strSrc => $strAttr) {
         $buffer .= $tab . '<link rel="stylesheet" href="' . $strSrc . '" type="' . $strAttr['mime'] . '"';
         if (!is_null($strAttr['media'])) {
             $buffer .= ' media="' . $strAttr['media'] . '" ';
         }
         if ($temp = ArrayHelper::toString($strAttr['attribs'])) {
             $buffer .= ' ' . $temp;
         }
         $buffer .= $tagEnd . $lnEnd;
     }
     // Generate stylesheet declarations
     foreach ($document->_style as $type => $content) {
         $buffer .= $tab . '<style type="' . $type . '">' . $lnEnd;
         // This is for full XHTML support.
         if ($document->_mime != 'text/html') {
             $buffer .= $tab . $tab . '<![CDATA[' . $lnEnd;
         }
         $buffer .= $content . $lnEnd;
         // See above note
         if ($document->_mime != 'text/html') {
             $buffer .= $tab . $tab . ']]>' . $lnEnd;
         }
         $buffer .= $tab . '</style>' . $lnEnd;
     }
     // Generate script file links
     foreach ($document->_scripts as $strSrc => $strAttr) {
         $buffer .= $tab . '<script src="' . $strSrc . '"';
         if (!is_null($strAttr['mime'])) {
             $buffer .= ' type="' . $strAttr['mime'] . '"';
         }
         if ($strAttr['defer']) {
             $buffer .= ' defer="defer"';
         }
         if ($strAttr['async']) {
             $buffer .= ' async="async"';
         }
         $buffer .= '></script>' . $lnEnd;
     }
     // Generate script declarations
     foreach ($document->_script as $type => $content) {
         $buffer .= $tab . '<script type="' . $type . '">' . $lnEnd;
         // This is for full XHTML support.
         if ($document->_mime != 'text/html') {
             $buffer .= $tab . $tab . '<![CDATA[' . $lnEnd;
         }
         $buffer .= $content . $lnEnd;
         // See above note
         if ($document->_mime != 'text/html') {
             $buffer .= $tab . $tab . ']]>' . $lnEnd;
         }
         $buffer .= $tab . '</script>' . $lnEnd;
     }
     // Generate script language declarations.
     if (count(Text::script())) {
         $buffer .= $tab . '<script type="text/javascript">' . $lnEnd;
         $buffer .= $tab . $tab . '(function() {' . $lnEnd;
         $buffer .= $tab . $tab . $tab . 'var strings = ' . json_encode(Text::script()) . ';' . $lnEnd;
         $buffer .= $tab . $tab . $tab . 'if (typeof Joomla == \'undefined\') {' . $lnEnd;
         $buffer .= $tab . $tab . $tab . $tab . 'Joomla = {};' . $lnEnd;
         $buffer .= $tab . $tab . $tab . $tab . 'Joomla.JText = strings;' . $lnEnd;
         $buffer .= $tab . $tab . $tab . '}' . $lnEnd;
         $buffer .= $tab . $tab . $tab . 'else {' . $lnEnd;
         $buffer .= $tab . $tab . $tab . $tab . 'Joomla.JText.load(strings);' . $lnEnd;
         $buffer .= $tab . $tab . $tab . '}' . $lnEnd;
         $buffer .= $tab . $tab . '})();' . $lnEnd;
         $buffer .= $tab . '</script>' . $lnEnd;
     }
     foreach ($document->_custom as $custom) {
         $buffer .= $tab . $custom . $lnEnd;
     }
     return $buffer;
 }
 /**
  * Render the feed.
  *
  * @param   string  $name     The name of the element to render
  * @param   array   $params   Array of values
  * @param   string  $content  Override the output of the renderer
  *
  * @return  string  The output of the script
  *
  * @see JDocumentRenderer::render()
  * @since   11.1
  */
 public function render($name = '', $params = null, $content = null)
 {
     $app = Factory::getApplication();
     // Gets and sets timezone offset from site configuration
     $tz = new DateTimeZone($app->getCfg('offset'));
     $now = Factory::getDate();
     $now->setTimeZone($tz);
     $data = $this->_doc;
     $uri = Uri::getInstance();
     $url = $uri->toString(array('scheme', 'user', 'pass', 'host', 'port'));
     $syndicationURL = Route::_('&format=feed&type=atom');
     if ($app->getCfg('sitename_pagetitles', 0) == 1) {
         $title = Text::sprintf('JPAGETITLE', $app->getCfg('sitename'), $data->title);
     } elseif ($app->getCfg('sitename_pagetitles', 0) == 2) {
         $title = Text::sprintf('JPAGETITLE', $data->title, $app->getCfg('sitename'));
     } else {
         $title = $data->title;
     }
     $feed_title = htmlspecialchars($title, ENT_COMPAT, 'UTF-8');
     $feed = "<feed xmlns=\"http://www.w3.org/2005/Atom\" ";
     if ($data->language != "") {
         $feed .= " xml:lang=\"" . $data->language . "\"";
     }
     $feed .= ">\n";
     $feed .= "\t<title type=\"text\">" . $feed_title . "</title>\n";
     $feed .= "\t<subtitle type=\"text\">" . htmlspecialchars($data->description, ENT_COMPAT, 'UTF-8') . "</subtitle>\n";
     if (empty($data->category) === false) {
         if (is_array($data->category)) {
             foreach ($data->category as $cat) {
                 $feed .= "\t<category term=\"" . htmlspecialchars($cat, ENT_COMPAT, 'UTF-8') . "\" />\n";
             }
         } else {
             $feed .= "\t<category term=\"" . htmlspecialchars($data->category, ENT_COMPAT, 'UTF-8') . "\" />\n";
         }
     }
     $feed .= "\t<link rel=\"alternate\" type=\"text/html\" href=\"" . $url . "\"/>\n";
     $feed .= "\t<id>" . str_replace(' ', '%20', $data->getBase()) . "</id>\n";
     $feed .= "\t<updated>" . htmlspecialchars($now->toISO8601(true), ENT_COMPAT, 'UTF-8') . "</updated>\n";
     if ($data->editor != "") {
         $feed .= "\t<author>\n";
         $feed .= "\t\t<name>" . $data->editor . "</name>\n";
         if ($data->editorEmail != "") {
             $feed .= "\t\t<email>" . htmlspecialchars($data->editorEmail, ENT_COMPAT, 'UTF-8') . "</email>\n";
         }
         $feed .= "\t</author>\n";
     }
     $feed .= "\t<generator uri=\"http://joomla.org\" version=\"1.6\">" . $data->getGenerator() . "</generator>\n";
     $feed .= '	<link rel="self" type="application/atom+xml" href="' . str_replace(' ', '%20', $url . $syndicationURL) . "\"/>\n";
     for ($i = 0, $count = count($data->items); $i < $count; $i++) {
         $feed .= "\t<entry>\n";
         $feed .= "\t\t<title>" . htmlspecialchars(strip_tags($data->items[$i]->title), ENT_COMPAT, 'UTF-8') . "</title>\n";
         $feed .= '		<link rel="alternate" type="text/html" href="' . $url . $data->items[$i]->link . "\"/>\n";
         if ($data->items[$i]->date == "") {
             $data->items[$i]->date = $now->toUnix();
         }
         $itemDate = Factory::getDate($data->items[$i]->date);
         $itemDate->setTimeZone($tz);
         $feed .= "\t\t<published>" . htmlspecialchars($itemDate->toISO8601(true), ENT_COMPAT, 'UTF-8') . "</published>\n";
         $feed .= "\t\t<updated>" . htmlspecialchars($itemDate->toISO8601(true), ENT_COMPAT, 'UTF-8') . "</updated>\n";
         if (empty($data->items[$i]->guid) === true) {
             $feed .= "\t\t<id>" . str_replace(' ', '%20', $url . $data->items[$i]->link) . "</id>\n";
         } else {
             $feed .= "\t\t<id>" . htmlspecialchars($data->items[$i]->guid, ENT_COMPAT, 'UTF-8') . "</id>\n";
         }
         if ($data->items[$i]->author != "") {
             $feed .= "\t\t<author>\n";
             $feed .= "\t\t\t<name>" . htmlspecialchars($data->items[$i]->author, ENT_COMPAT, 'UTF-8') . "</name>\n";
             if ($data->items[$i]->authorEmail != "") {
                 $feed .= "\t\t\t<email>" . htmlspecialchars($data->items[$i]->authorEmail, ENT_COMPAT, 'UTF-8') . "</email>\n";
             }
             $feed .= "\t\t</author>\n";
         }
         if ($data->items[$i]->description != "") {
             $feed .= "\t\t<summary type=\"html\">" . htmlspecialchars($data->items[$i]->description, ENT_COMPAT, 'UTF-8') . "</summary>\n";
             $feed .= "\t\t<content type=\"html\">" . htmlspecialchars($data->items[$i]->description, ENT_COMPAT, 'UTF-8') . "</content>\n";
         }
         if (empty($data->items[$i]->category) === false) {
             if (is_array($data->items[$i]->category)) {
                 foreach ($data->items[$i]->category as $cat) {
                     $feed .= "\t\t<category term=\"" . htmlspecialchars($cat, ENT_COMPAT, 'UTF-8') . "\" />\n";
                 }
             } else {
                 $feed .= "\t\t<category term=\"" . htmlspecialchars($data->items[$i]->category, ENT_COMPAT, 'UTF-8') . "\" />\n";
             }
         }
         if ($data->items[$i]->enclosure != null) {
             $feed .= "\t\t<link rel=\"enclosure\" href=\"" . $data->items[$i]->enclosure->url . "\" type=\"" . $data->items[$i]->enclosure->type . "\"  length=\"" . $data->items[$i]->enclosure->length . "\" />\n";
         }
         $feed .= "\t</entry>\n";
     }
     $feed .= "</feed>\n";
     return $feed;
 }
 /**
  * Render the feed.
  *
  * @param   string  $name     The name of the element to render
  * @param   array   $params   Array of values
  * @param   string  $content  Override the output of the renderer
  *
  * @return  string  The output of the script
  *
  * @see JDocumentRenderer::render()
  * @since   11.1
  */
 public function render($name = '', $params = null, $content = null)
 {
     $app = Factory::getApplication();
     // Gets and sets timezone offset from site configuration
     $tz = new DateTimeZone($app->getCfg('offset'));
     $now = Factory::getDate();
     $now->setTimeZone($tz);
     $data = $this->_doc;
     $uri = Uri::getInstance();
     $url = $uri->toString(array('scheme', 'user', 'pass', 'host', 'port'));
     $syndicationURL = Route::_('&format=feed&type=rss');
     if ($app->getCfg('sitename_pagetitles', 0) == 1) {
         $title = Text::sprintf('JPAGETITLE', $app->getCfg('sitename'), $data->title);
     } elseif ($app->getCfg('sitename_pagetitles', 0) == 2) {
         $title = Text::sprintf('JPAGETITLE', $data->title, $app->getCfg('sitename'));
     } else {
         $title = $data->title;
     }
     $feed_title = htmlspecialchars($title, ENT_COMPAT, 'UTF-8');
     $feed = "<rss version=\"2.0\" xmlns:atom=\"http://www.w3.org/2005/Atom\">\n";
     $feed .= "\t<channel>\n";
     $feed .= "\t\t<title>" . $feed_title . "</title>\n";
     $feed .= "\t\t<description><![CDATA[" . $data->description . "]]></description>\n";
     $feed .= "\t\t<link>" . str_replace(' ', '%20', $url . $data->link) . "</link>\n";
     $feed .= "\t\t<lastBuildDate>" . htmlspecialchars($now->toRFC822(true), ENT_COMPAT, 'UTF-8') . "</lastBuildDate>\n";
     $feed .= "\t\t<generator>" . $data->getGenerator() . "</generator>\n";
     $feed .= '		<atom:link rel="self" type="application/rss+xml" href="' . str_replace(' ', '%20', $url . $syndicationURL) . "\"/>\n";
     if ($data->image != null) {
         $feed .= "\t\t<image>\n";
         $feed .= "\t\t\t<url>" . $data->image->url . "</url>\n";
         $feed .= "\t\t\t<title>" . htmlspecialchars($data->image->title, ENT_COMPAT, 'UTF-8') . "</title>\n";
         $feed .= "\t\t\t<link>" . str_replace(' ', '%20', $data->image->link) . "</link>\n";
         if ($data->image->width != "") {
             $feed .= "\t\t\t<width>" . $data->image->width . "</width>\n";
         }
         if ($data->image->height != "") {
             $feed .= "\t\t\t<height>" . $data->image->height . "</height>\n";
         }
         if ($data->image->description != "") {
             $feed .= "\t\t\t<description><![CDATA[" . $data->image->description . "]]></description>\n";
         }
         $feed .= "\t\t</image>\n";
     }
     if ($data->language != "") {
         $feed .= "\t\t<language>" . $data->language . "</language>\n";
     }
     if ($data->copyright != "") {
         $feed .= "\t\t<copyright>" . htmlspecialchars($data->copyright, ENT_COMPAT, 'UTF-8') . "</copyright>\n";
     }
     if ($data->editorEmail != "") {
         $feed .= "\t\t<managingEditor>" . htmlspecialchars($data->editorEmail, ENT_COMPAT, 'UTF-8') . ' (' . htmlspecialchars($data->editor, ENT_COMPAT, 'UTF-8') . ")</managingEditor>\n";
     }
     if ($data->webmaster != "") {
         $feed .= "\t\t<webMaster>" . htmlspecialchars($data->webmaster, ENT_COMPAT, 'UTF-8') . "</webMaster>\n";
     }
     if ($data->pubDate != "") {
         $pubDate = JFactory::getDate($data->pubDate);
         $pubDate->setTimeZone($tz);
         $feed .= "\t\t<pubDate>" . htmlspecialchars($pubDate->toRFC822(true), ENT_COMPAT, 'UTF-8') . "</pubDate>\n";
     }
     if (empty($data->category) === false) {
         if (is_array($data->category)) {
             foreach ($data->category as $cat) {
                 $feed .= "\t\t<category>" . htmlspecialchars($cat, ENT_COMPAT, 'UTF-8') . "</category>\n";
             }
         } else {
             $feed .= "\t\t<category>" . htmlspecialchars($data->category, ENT_COMPAT, 'UTF-8') . "</category>\n";
         }
     }
     if ($data->docs != "") {
         $feed .= "\t\t<docs>" . htmlspecialchars($data->docs, ENT_COMPAT, 'UTF-8') . "</docs>\n";
     }
     if ($data->ttl != "") {
         $feed .= "\t\t<ttl>" . htmlspecialchars($data->ttl, ENT_COMPAT, 'UTF-8') . "</ttl>\n";
     }
     if ($data->rating != "") {
         $feed .= "\t\t<rating>" . htmlspecialchars($data->rating, ENT_COMPAT, 'UTF-8') . "</rating>\n";
     }
     if ($data->skipHours != "") {
         $feed .= "\t\t<skipHours>" . htmlspecialchars($data->skipHours, ENT_COMPAT, 'UTF-8') . "</skipHours>\n";
     }
     if ($data->skipDays != "") {
         $feed .= "\t\t<skipDays>" . htmlspecialchars($data->skipDays, ENT_COMPAT, 'UTF-8') . "</skipDays>\n";
     }
     for ($i = 0, $count = count($data->items); $i < $count; $i++) {
         if (strpos($data->items[$i]->link, 'http://') === false && strpos($data->items[$i]->link, 'https://') === false) {
             $data->items[$i]->link = str_replace(' ', '%20', $url . $data->items[$i]->link);
         }
         $feed .= "\t\t<item>\n";
         $feed .= "\t\t\t<title>" . htmlspecialchars(strip_tags($data->items[$i]->title), ENT_COMPAT, 'UTF-8') . "</title>\n";
         $feed .= "\t\t\t<link>" . str_replace(' ', '%20', $data->items[$i]->link) . "</link>\n";
         if (empty($data->items[$i]->guid) === true) {
             $feed .= "\t\t\t<guid isPermaLink=\"true\">" . str_replace(' ', '%20', $data->items[$i]->link) . "</guid>\n";
         } else {
             $feed .= "\t\t\t<guid isPermaLink=\"false\">" . htmlspecialchars($data->items[$i]->guid, ENT_COMPAT, 'UTF-8') . "</guid>\n";
         }
         $feed .= "\t\t\t<description><![CDATA[" . $this->_relToAbs($data->items[$i]->description) . "]]></description>\n";
         if ($data->items[$i]->authorEmail != "") {
             $feed .= "\t\t\t<author>" . htmlspecialchars($data->items[$i]->authorEmail . ' (' . $data->items[$i]->author . ')', ENT_COMPAT, 'UTF-8') . "</author>\n";
         }
         /*
          * @todo: On hold
          * if ($data->items[$i]->source!="") {
          *   $data.= "			<source>".htmlspecialchars($data->items[$i]->source, ENT_COMPAT, 'UTF-8')."</source>\n";
          * }
          */
         if (empty($data->items[$i]->category) === false) {
             if (is_array($data->items[$i]->category)) {
                 foreach ($data->items[$i]->category as $cat) {
                     $feed .= "\t\t\t<category>" . htmlspecialchars($cat, ENT_COMPAT, 'UTF-8') . "</category>\n";
                 }
             } else {
                 $feed .= "\t\t\t<category>" . htmlspecialchars($data->items[$i]->category, ENT_COMPAT, 'UTF-8') . "</category>\n";
             }
         }
         if ($data->items[$i]->comments != "") {
             $feed .= "\t\t\t<comments>" . htmlspecialchars($data->items[$i]->comments, ENT_COMPAT, 'UTF-8') . "</comments>\n";
         }
         if ($data->items[$i]->date != "") {
             $itemDate = Factory::getDate($data->items[$i]->date);
             $itemDate->setTimeZone($tz);
             $feed .= "\t\t\t<pubDate>" . htmlspecialchars($itemDate->toRFC822(true), ENT_COMPAT, 'UTF-8') . "</pubDate>\n";
         }
         if ($data->items[$i]->enclosure != null) {
             $feed .= "\t\t\t<enclosure url=\"";
             $feed .= $data->items[$i]->enclosure->url;
             $feed .= "\" length=\"";
             $feed .= $data->items[$i]->enclosure->length;
             $feed .= "\" type=\"";
             $feed .= $data->items[$i]->enclosure->type;
             $feed .= "\"/>\n";
         }
         $feed .= "\t\t</item>\n";
     }
     $feed .= "\t</channel>\n";
     $feed .= "</rss>\n";
     return $feed;
 }
 /**
  * Render the document
  *
  * @param   boolean  $cache   If true, cache the output
  * @param   array    $params  Associative array of attributes
  *
  * @return  The rendered data
  *
  * @since  11.1
  * @throws Exception
  * @todo   Make this cacheable
  */
 public function render($cache = false, $params = array())
 {
     // Get the feed type
     $type = Factory::getApplication()->input->get('type', 'rss');
     // Instantiate feed renderer and set the mime encoding
     $renderer = $this->loadRenderer($type ? $type : 'rss');
     if (!is_a($renderer, '\\Joomla\\Document\\Renderer')) {
         throw new Exception(Text::_('JGLOBAL_RESOURCE_NOT_FOUND'), 404);
     }
     $this->setMimeEncoding($renderer->getContentType());
     // Output
     // Generate prolog
     $data = "<?xml version=\"1.0\" encoding=\"" . $this->_charset . "\"?>\n";
     $data .= "<!-- generator=\"" . $this->getGenerator() . "\" -->\n";
     // Generate stylesheet links
     foreach ($this->_styleSheets as $src => $attr) {
         $data .= "<?xml-stylesheet href=\"{$src}\" type=\"" . $attr['mime'] . "\"?>\n";
     }
     // Render the feed
     $data .= $renderer->render();
     parent::render();
     return $data;
 }
 /**
  * Load the application object.
  *
  * @return  JApplicationBase  The application object.
  *
  * @since   12.1
  */
 protected function loadApplication()
 {
     return Factory::getApplication();
 }
 /**
  * Get available languages
  *
  * @param   string  $key  Array key
  *
  * @return  array  An array of published languages
  *
  * @since   11.1
  */
 public static function getLanguages($key = 'default')
 {
     static $languages;
     if (empty($languages)) {
         // Installation uses available languages
         if (Factory::getApplication()->getClientId() == 2) {
             $languages[$key] = array();
             $knownLangs = Language::getKnownLanguages(JPATH_BASE);
             foreach ($knownLangs as $metadata) {
                 // Take off 3 letters iso code languages as they can't match browsers' languages and default them to en
                 $obj = new stdClass();
                 $obj->lang_code = $metadata['tag'];
                 $languages[$key][] = $obj;
             }
         } else {
             $cache = Factory::getCache('com_languages', '');
             if (!($languages = $cache->get('languages'))) {
                 $db = Factory::getDBO();
                 $query = $db->getQuery(true);
                 $query->select('*')->from('#__languages')->where('published=1')->order('ordering ASC');
                 $db->setQuery($query);
                 $languages['default'] = $db->loadObjectList();
                 $languages['sef'] = array();
                 $languages['lang_code'] = array();
                 if (isset($languages['default'][0])) {
                     foreach ($languages['default'] as $lang) {
                         $languages['sef'][$lang->sef] = $lang;
                         $languages['lang_code'][$lang->lang_code] = $lang;
                     }
                 }
                 $cache->store($languages, 'languages');
             }
         }
     }
     return $languages[$key];
 }